Użyłem poniższych informacji przez pewien czas. Pierwotnie pochodzi z here.
namespace SerializeDictionary
{
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
/// <summary>
/// Represents an XML serializable collection of keys and values.
/// </summary>
/// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
/// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
[Serializable]
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
/// <summary>
/// The default XML tag name for an item.
/// </summary>
private const string DefaultItemTag = "item";
/// <summary>
/// The default XML tag name for a key.
/// </summary>
private const string DefaultKeyTag = "key";
/// <summary>
/// The default XML tag name for a value.
/// </summary>
private const string DefaultValueTag = "value";
/// <summary>
/// The XML serializer for the key type.
/// </summary>
private static readonly XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
/// <summary>
/// The XML serializer for the value type.
/// </summary>
private static readonly XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
/// <summary>
/// Initializes a new instance of the
/// <see cref="SerializableDictionary<TKey, TValue>"/> class.
/// </summary>
public SerializableDictionary()
{
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="SerializableDictionary<TKey, TValue>"/> class.
/// </summary>
/// <param name="info">A
/// <see cref="T:System.Runtime.Serialization.SerializationInfo"/> object
/// containing the information required to serialize the
/// <see cref="T:System.Collections.Generic.Dictionary`2"/>.
/// </param>
/// <param name="context">A
/// <see cref="T:System.Runtime.Serialization.StreamingContext"/> structure
/// containing the source and destination of the serialized stream
/// associated with the
/// <see cref="T:System.Collections.Generic.Dictionary`2"/>.
/// </param>
protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
/// <summary>
/// Gets the XML tag name for an item.
/// </summary>
protected virtual string ItemTagName
{
get
{
return DefaultItemTag;
}
}
/// <summary>
/// Gets the XML tag name for a key.
/// </summary>
protected virtual string KeyTagName
{
get
{
return DefaultKeyTag;
}
}
/// <summary>
/// Gets the XML tag name for a value.
/// </summary>
protected virtual string ValueTagName
{
get
{
return DefaultValueTag;
}
}
/// <summary>
/// Gets the XML schema for the XML serialization.
/// </summary>
/// <returns>An XML schema for the serialized object.</returns>
public XmlSchema GetSchema()
{
return null;
}
/// <summary>
/// Deserializes the object from XML.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
public void ReadXml(XmlReader reader)
{
var wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
{
return;
}
try
{
while (reader.NodeType != XmlNodeType.EndElement)
{
this.ReadItem(reader);
reader.MoveToContent();
}
}
finally
{
reader.ReadEndElement();
}
}
/// <summary>
/// Serializes this instance to XML.
/// </summary>
/// <param name="writer">The XML writer to serialize to.</param>
public void WriteXml(XmlWriter writer)
{
foreach (var keyValuePair in this)
{
this.WriteItem(writer, keyValuePair);
}
}
/// <summary>
/// Deserializes the dictionary item.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
private void ReadItem(XmlReader reader)
{
reader.ReadStartElement(this.ItemTagName);
try
{
this.Add(this.ReadKey(reader), this.ReadValue(reader));
}
finally
{
reader.ReadEndElement();
}
}
/// <summary>
/// Deserializes the dictionary item's key.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
/// <returns>The dictionary item's key.</returns>
private TKey ReadKey(XmlReader reader)
{
reader.ReadStartElement(this.KeyTagName);
try
{
return (TKey)keySerializer.Deserialize(reader);
}
finally
{
reader.ReadEndElement();
}
}
/// <summary>
/// Deserializes the dictionary item's value.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
/// <returns>The dictionary item's value.</returns>
private TValue ReadValue(XmlReader reader)
{
reader.ReadStartElement(this.ValueTagName);
try
{
return (TValue)valueSerializer.Deserialize(reader);
}
finally
{
reader.ReadEndElement();
}
}
/// <summary>
/// Serializes the dictionary item.
/// </summary>
/// <param name="writer">The XML writer to serialize to.</param>
/// <param name="keyValuePair">The key/value pair.</param>
private void WriteItem(XmlWriter writer, KeyValuePair<TKey, TValue> keyValuePair)
{
writer.WriteStartElement(this.ItemTagName);
try
{
this.WriteKey(writer, keyValuePair.Key);
this.WriteValue(writer, keyValuePair.Value);
}
finally
{
writer.WriteEndElement();
}
}
/// <summary>
/// Serializes the dictionary item's key.
/// </summary>
/// <param name="writer">The XML writer to serialize to.</param>
/// <param name="key">The dictionary item's key.</param>
private void WriteKey(XmlWriter writer, TKey key)
{
writer.WriteStartElement(this.KeyTagName);
try
{
keySerializer.Serialize(writer, key);
}
finally
{
writer.WriteEndElement();
}
}
/// <summary>
/// Serializes the dictionary item's value.
/// </summary>
/// <param name="writer">The XML writer to serialize to.</param>
/// <param name="value">The dictionary item's value.</param>
private void WriteValue(XmlWriter writer, TValue value)
{
writer.WriteStartElement(this.ValueTagName);
try
{
valueSerializer.Serialize(writer, value);
}
finally
{
writer.WriteEndElement();
}
}
}
}
Mam dobry raport, że słowniki można szeregować w .NET 4.0. – kbrimington
Jak to zrobić z nazwami i atrybutami niestandardowych elementów? – Burnzy
Zobacz [Jedną z możliwości szeregowania słowników] (http://johnwsaundersiii.spaces.live.com/blog/cns!600A2BE4A82EA0A6!699.entry). –