【问题标题】:How to serialize a class containing queues for XML?如何序列化包含 XML 队列的类?
【发布时间】:2014-11-24 12:26:46
【问题描述】:

我有一个名为 GamePrototype 的类,我想序列化它以供 XML 使用,它包含以下成员:

public class GamePrototype
{
    private string mPath;
    private bool[] isHumanPlayer;
    private Queue<CardPrototype> mKickStack;
    private Queue<CardPrototype> mMainDeck;
    private Queue<CardPrototype> mStarterDecks;
    private Queue<CardPrototype> mSuperVillianStack;
    private Queue<CardPrototype> mWeaknessStack;
    private Queue<PlayerHero> mPlayableHeroes;
    public Queue<CardPrototype>[] mStartingLocations;
}

我一直在尝试用这种方法序列化类数据。 “this”指的是上述类的一个实例:

public void XMLShelf(string path)
    {
        XmlSerializer boxPacker = new XmlSerializer(typeof(GamePrototype));
        StreamWriter boxPlacer = new StreamWriter(path);

        boxPacker.Serialize(boxPlacer, this);
        boxPlacer.Close();
    }

我有大多数(如果不是全部)getter 和 setter,但我遇到了两个我不知道如何避免的错误:

Exception:Thrown: "You must implement a default accessor on 
System.Collections.Generic.Queue`1[[Cards.GameBuilding.CardPrototype, Cards, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] because it inherits from 
ICollection."...

Exception:Thrown: "There was an error reflecting type 
'Cards.GameBuilding.GamePrototype'." (System.InvalidOperationException)

我在其他帖子中读到,在当前情况下,由于队列,这个类是不可序列化的。这些信息可能已经过时了?我不确定,但我的问题是:

有没有一种方法可以轻松地将这些队列转移到列表中以进行序列化? 我是否也需要对这些成员所属的所有班级执行此操作?例如,卡片原型包含一个队列和一个堆栈。

非常感谢您给我的任何帮助。

【问题讨论】:

  • Queue<T> 具有 Serializable 属性,所以我认为这不是您无法序列化的原因。请添加您拥有的代码(您写道,您有它们的属性,任何属性?),您得到的异常,您使用什么样的序列化程序以及您如何序列化。
  • 请出错 - 准确,而不是“喜欢”。
  • 我更新了我的帖子,并添加了我在调试过程中注意到的第二个异常。

标签: c# xml inheritance serialization queue


【解决方案1】:

这取决于您使用的序列化。 使用 ISerializable 就可以了。

[Serializable]
class Program : ISerializable
{
    public Program() { }

    public Queue<int> Queue = new Queue<int>(); 

    private unsafe static void Main(string[] args)
    {
        var pr = new Program();
        pr.Queue.Enqueue(1034);

        using (var stream = File.Create("path.txt"))
        {
            var bformatter = new BinaryFormatter();
            bformatter.Serialize(stream, pr);
        }

        using (var stream = File.Open("path.txt", FileMode.Open))
        {
            var bformatter = new BinaryFormatter();
            pr = (Program)bformatter.Deserialize(stream);
        }

        Console.WriteLine("program " + pr.Queue.Peek()); //prints 1034
        Console.Read();
    }

    public Program(SerializationInfo info, StreamingContext ctxt)
    {
        Queue = (Queue<int>)info.GetValue("queue", typeof(Queue<int>));
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("queue", Queue);
    }
}

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您必须为 Queue 实现默认访问器,因为 XMLSerializer 需要它来枚举项目以及 Add 方法。

    [Serializable]
    public class SerializableQueue : Queue<MyObject>
    {
        public MyObject this[int index]
        {
            get
            {
                int count = 0;
                foreach (MyObject o in this)
                {
                    if (count == index)
                        return o;
                    count++;
                }
                return null;
            }
        }
    
        public void Add(MyObject r)
        {
            Enqueue(r);   
        }
    }
    

    这是一个可以序列化为 XML 的队列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 2011-01-28
      • 1970-01-01
      • 2014-07-02
      • 1970-01-01
      相关资源
      最近更新 更多