繁体   English   中英

如何正确序列化和反序列化字典的值?

[英]How do I serialize and deserialize a dictionary's values correctly?

我正在尝试找出正确的方法。 到目前为止,我正在使用此方法来序列化对象列表:

var serializer = new System.Xml.Serialization.XmlSerializer(typeof(MyInfo));
using (var writer = new StreamWriter("SerializedValues.xml"))
{
    foreach (var o in dic.Values)
        serializer.Serialize(writer, o);
}

它变成了一个单独的XML文件的列表,每个文件都有自己的标头,但都在一个文件中。 我认为那是不对的。

然后,我尝试将其反序列化,这给了我以下错误:

意外的XML声明。 XML声明必须是文档中的第一个节点,并且不允许在其之前出现空格字符。 第5行,位置17。

而这正是下一个XML标头开始的地方。 所以我想我将其序列化了。

还有一个问题来自反序列化返回单个对象的事实,这听起来似乎是错误的,因为我希望有一个排序列表。

如何正确序列化它?

如何序列化整个字典?

编辑:好的,如何作为KeyValuePair的列表?

var list = dic.ToList();
XmlSerializer s = new XmlSerializer(list.GetType());
using (StreamWriter file = new StreamWriter("SerializedValues.xml"))
    s.Serialize(file, list);

我设法通过在序列化之前将值转换为数组来做到这一点:

var serializer = new System.Xml.Serialization.XmlSerializer(typeof(MyInfo[]));
using (var writer = new StreamWriter("SerializedValues.xml"))
{
    serializer.Serialize(writer, dic.Values.ToArray());
}

并反序列化如下:

using (var reader = new StreamReader("SerializedValues.xml"))
{
    var array = (MyInfo[])serializer.Deserialize(reader);
    foreach (var v in array)                
        dic[v.id] = v;
}           

尽管您的解决方案适用于这一特定情况-因为值也包含有关键的信息-我仍然会寻求更通用的解决方案。

即使Value没有关于密钥的信息,agentnega的修改后的答案也将起作用。

我最喜欢的是SerializableDictionary。 因为(反)序列化没有其他工作! 从此处获取: http : //csharpcodewhisperer.blogspot.co.at/2013/06/namespace-xmlserializabledictionary.html

namespace XMLSerializableDictionary
{
  using System;
  using System.Collections.Generic;
  using System.Runtime.Serialization;
  using System.Xml;
  using System.Xml.Schema;
  using System.Xml.Serialization;

  [Serializable]
  [XmlRoot("Dictionary")]
  public class SerializableDictionary<TKey, TValue>
    : Dictionary<TKey, TValue>, IXmlSerializable
  {
    private const string DefaultTagItem = "Item";
    private const string DefaultTagKey = "Key";
    private const string DefaultTagValue = "Value";
    private static readonly XmlSerializer KeySerializer =
                                    new XmlSerializer(typeof(TKey));

    private static readonly XmlSerializer ValueSerializer =
                                    new XmlSerializer(typeof(TValue));

    public SerializableDictionary() : base()
    {
    }

    protected SerializableDictionary(SerializationInfo info, StreamingContext context)
            : base(info, context)
    {
    }

    protected virtual string ItemTagName
    {
        get { return DefaultTagItem; }
    }

    protected virtual string KeyTagName
    {
        get { return DefaultTagKey; }
    }

    protected virtual string ValueTagName
    {
        get { return DefaultTagValue; }
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        bool wasEmpty = reader.IsEmptyElement;

        reader.Read();

        if (wasEmpty)
        {
         return;
        }

        try
        {
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement(this.ItemTagName);
                try
                {
                    TKey tKey;
                    TValue tValue;

                    reader.ReadStartElement(this.KeyTagName);
                    try
                    {
                        tKey = (TKey)KeySerializer.Deserialize(reader);
                    }
                    finally
                    {
                        reader.ReadEndElement();
                    }

                    reader.ReadStartElement(this.ValueTagName);
                    try
                    {
                        tValue = (TValue)ValueSerializer.Deserialize(reader);
                    }
                    finally
                    {
                        reader.ReadEndElement();
                    }

                    this.Add(tKey, tValue);
                }
                finally
                {
                    reader.ReadEndElement();
                }

                reader.MoveToContent();
            }
        }
        finally
        {
            reader.ReadEndElement();
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        foreach (KeyValuePair<TKey, TValue> keyValuePair in this)
        {
            writer.WriteStartElement(this.ItemTagName);
            try
            {
                writer.WriteStartElement(this.KeyTagName);
                try
                {
                    KeySerializer.Serialize(writer, keyValuePair.Key);
                }
                finally
                {
                    writer.WriteEndElement();
                }

                writer.WriteStartElement(this.ValueTagName);
                try
                {
                    ValueSerializer.Serialize(writer, keyValuePair.Value);
                }
                finally
                {
                    writer.WriteEndElement();
                }
            }
            finally
            {
                writer.WriteEndElement();
            }
        }
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM