序列化.NET字典

可能重复:
Serialize包含Dictionary成员的类

我可以序列化一个字典吗?

哪个序列化API?

例如, DataContractSerializer可以处理字典,特别是使用(可选) [CollectionDataContract]标记。 protobuf-net将处理它们(下图)。 其他人可能不…

  var data = new Dictionary(); data.Add("abc", 123); data.Add("def", 456); var clone = Serializer.DeepClone(data); Console.WriteLine(clone["abc"]); Console.WriteLine(clone["def"]); 

BinaryFormatter

  using (MemoryStream ms = new MemoryStream()) { var bf = new BinaryFormatter(); bf.Serialize(ms, data); ms.Position = 0; clone = (Dictionary) bf.Deserialize(ms); } 

不是没有使用其他序列化库或自己实现序列化。 Hashtable或Dictionary都不能在.NET中开箱即用。 这里有一个SerializableDictionary的实现,它同时执行XML和二进制序列化。

以下是链接中的代码(版权所有(c)Dacris Software Inc. MIT许可证):

 using System; using System.Runtime.Serialization; using System.Xml; using System.Xml.Serialization; using System.Collections.Generic; using System.Text; [Serializable()] public class SerializableDictionary : Dictionary, IXmlSerializable, ISerializable { #region Constants private const string DictionaryNodeName = "Dictionary"; private const string ItemNodeName = "Item"; private const string KeyNodeName = "Key"; private const string ValueNodeName = "Value"; #endregion #region Constructors public SerializableDictionary() { } public SerializableDictionary(IDictionary dictionary) : base(dictionary) { } public SerializableDictionary(IEqualityComparer comparer) : base(comparer) { } public SerializableDictionary(int capacity) : base(capacity) { } public SerializableDictionary(IDictionary dictionary, IEqualityComparer comparer) : base(dictionary, comparer) { } public SerializableDictionary(int capacity, IEqualityComparer comparer) : base(capacity, comparer) { } #endregion #region ISerializable Members protected SerializableDictionary(SerializationInfo info, StreamingContext context) { int itemCount = info.GetInt32("ItemCount"); for (int i = 0; i < itemCount; i++) { KeyValuePair kvp = (KeyValuePair)info.GetValue(String.Format("Item{0}", i), typeof(KeyValuePair)); this.Add(kvp.Key, kvp.Value); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("ItemCount", this.Count); int itemIdx = 0; foreach (KeyValuePair kvp in this) { info.AddValue(String.Format("Item{0}", itemIdx), kvp, typeof(KeyValuePair)); itemIdx++; } } #endregion #region IXmlSerializable Members void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) { //writer.WriteStartElement(DictionaryNodeName); foreach (KeyValuePair kvp in this) { writer.WriteStartElement(ItemNodeName); writer.WriteStartElement(KeyNodeName); KeySerializer.Serialize(writer, kvp.Key); writer.WriteEndElement(); writer.WriteStartElement(ValueNodeName); ValueSerializer.Serialize(writer, kvp.Value); writer.WriteEndElement(); writer.WriteEndElement(); } //writer.WriteEndElement(); } void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) { if (reader.IsEmptyElement) { return; } // Move past container if (!reader.Read()) { throw new XmlException("Error in Deserialization of Dictionary"); } //reader.ReadStartElement(DictionaryNodeName); while (reader.NodeType != XmlNodeType.EndElement) { reader.ReadStartElement(ItemNodeName); reader.ReadStartElement(KeyNodeName); TKey key = (TKey)KeySerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadStartElement(ValueNodeName); TVal value = (TVal)ValueSerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadEndElement(); this.Add(key, value); reader.MoveToContent(); } //reader.ReadEndElement(); reader.ReadEndElement(); // Read End Element to close Read of containing node } System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() { return null; } #endregion #region Private Properties protected XmlSerializer ValueSerializer { get { if (valueSerializer == null) { valueSerializer = new XmlSerializer(typeof(TVal)); } return valueSerializer; } } private XmlSerializer KeySerializer { get { if (keySerializer == null) { keySerializer = new XmlSerializer(typeof(TKey)); } return keySerializer; } } #endregion #region Private Members private XmlSerializer keySerializer = null; private XmlSerializer valueSerializer = null; #endregion }