2014-02-11 107 views
1

我想弄清楚如何做到這一點。到目前爲止,我用這種方法序列化對象的列表:如何正確序列化和反序列化字典的值?

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文件的列表,每一個都有自己的頭,但都在一個文件中。我認爲這是不對的。

然後我嘗試反序列化它,它給了我下面的錯誤:

Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line 5, position 17.

而這正是下一個XML頭開始的地方。所以我想我的序列化是錯誤的。

還有一個問題來自事實,反序列化返回一個單一的對象,這已經聽起來不對,因爲我期待着一個排序列表。

如何正確地序列化它?

回答

1

如何序列化整個詞典?

編輯:好的,作爲KeyValuePair列表如何?

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

'System.NotSupportedException:類型System.Collections.Generic.Dictionary''2 [[System.String,誇誇其談],[MyProject.MyInfo,誇誇其談]是不支持,因爲它實現了IDictionary.' – user1306322

0

我設法之前序列化的值轉換爲數組做到這一點:

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; 
}   
0

雖然你的解決方案適用於這一個具體的情況 - 因爲價值也有關鍵的信息 - 我仍然會去尋求一個更一般的解決方案。

即使價值沒有關於密鑰的信息,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(); 
      } 
     } 
    } 
    } 
} 
+0

在我的情況下,密鑰可以是一個屬性,從所有對象的字段值返回哈希和。 – user1306322