15 01 2014
SerializableDictionary
Some days ago i got the problem, that I have to use a custom dictionary with
I found an interessting solution from “Paul Welter” at his blog (XML Serializable Generic Dictionary).
But that’s not all! I had to implement the Constructors for Dictionary and Serialization manually.
This is the final version for a generic Dictionary with the correct Constructors and attributes. I also added an overladed ToString method.
Hope you will enjoy 🙂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Xml.Serialization; [Serializable] [XmlRoot("dictionary")] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable { private const string Format = "{0}{{0}}{0}={1}{{1}}{1}"; public SerializableDictionary() : base() { } public SerializableDictionary(IDictionary<TKey, TValue> dictionary) : base(dictionary) { } public SerializableDictionary(IEqualityComparer<TKey> comparer) : base(comparer) { } public SerializableDictionary(int capacity) : base(capacity) { } public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) : base(dictionary, comparer) { } public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer) : base(capacity, comparer) { } protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { } public System.Xml.Schema.XmlSchema GetSchema() { return null; } public void ReadXml(System.Xml.XmlReader reader) { XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); bool wasEmpty = reader.IsEmptyElement; reader.Read(); if (wasEmpty) { return; } while (reader.NodeType != System.Xml.XmlNodeType.EndElement) { reader.ReadStartElement("item"); reader.ReadStartElement("key"); TKey key = (TKey)keySerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadStartElement("value"); TValue value = (TValue)valueSerializer.Deserialize(reader); reader.ReadEndElement(); this.Add(key, value); reader.ReadEndElement(); reader.MoveToContent(); } reader.ReadEndElement(); } public void WriteXml(System.Xml.XmlWriter writer) { XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); foreach (TKey key in this.Keys) { writer.WriteStartElement("item"); writer.WriteStartElement("key"); keySerializer.Serialize(writer, key); writer.WriteEndElement(); writer.WriteStartElement("value"); TValue value = this[key]; valueSerializer.Serialize(writer, value); writer.WriteEndElement(); writer.WriteEndElement(); } } public override string ToString() { return this.ToString(","); } public string ToString(string delimitter, bool useKeyQuotes = false, bool useValueQuotes = true, string keyQuotes = "\"", string valueQuotes = "\"") { string formatString = string.Format(Format, useKeyQuotes ? keyQuotes : string.Empty, useValueQuotes ? valueQuotes : string.Empty); return this.Keys.Aggregate(string.Empty, (current, next) => string.Concat(current, (current.Length == 0) ? string.Format(formatString, next, this[next]) : string.Concat(delimitter, string.Format(formatString, next, this[next])))); } } |
Share :
Indexed Properties Why is it bad to use return, break or continue in a finally block