/Collections/Generic/SerializableDictionary.cs |
@@ -18,22 +18,58 @@ |
/// </summary> |
/// <typeparam name="TKey">the key</typeparam> |
/// <typeparam name="TValue">the value</typeparam> |
[XmlRoot("Dictionary")] |
public class SerializableDictionary<TKey, TValue> |
: Dictionary<TKey, TValue>, IXmlSerializable |
{ |
#region IXmlSerializable Members |
public XmlSchema GetSchema() |
{ |
return null; |
} |
|
public SerializableDictionary(IEnumerable<KeyValuePair<TKey, TValue>> kvp) |
public void ReadXml(XmlReader reader) |
{ |
foreach (var i in kvp) |
if (reader.IsEmptyElement) |
{ |
Add(i.Key, i.Value); |
return; |
} |
|
reader.ReadStartElement(); |
while (!reader.NodeType.Equals(XmlNodeType.EndElement)) |
{ |
reader.ReadStartElement(ItemNodeName); |
|
reader.ReadStartElement(KeyNodeName); |
var key = (TKey) KeySerializer.Deserialize(reader); |
reader.ReadEndElement(); |
|
reader.ReadStartElement(ValueNodeName); |
var value = (TValue) ValueSerializer.Deserialize(reader); |
reader.ReadEndElement(); |
|
Add(key, value); |
|
reader.ReadEndElement(); |
reader.MoveToContent(); |
} |
reader.ReadEndElement(); |
} |
|
public SerializableDictionary() |
public void WriteXml(XmlWriter writer) |
{ |
foreach (var key in Keys) |
{ |
writer.WriteStartElement(ItemNodeName); |
|
writer.WriteStartElement(KeyNodeName); |
KeySerializer.Serialize(writer, key); |
writer.WriteEndElement(); |
|
writer.WriteStartElement(ValueNodeName); |
ValueSerializer.Serialize(writer, this[key]); |
writer.WriteEndElement(); |
|
writer.WriteEndElement(); |
} |
} |
|
/// <summary> |
@@ -45,17 +81,16 @@ |
SerializableDictionary<TKey, TValue> clone; |
try |
{ |
using (var writer = new MemoryStream()) |
using (var memoryStream = new MemoryStream()) |
{ |
var serializer = |
new XmlSerializer( |
typeof(SerializableDictionary<TKey, TValue>)); |
serializer.Serialize(writer, this); |
writer.Seek(0, SeekOrigin.Begin); |
new XmlSerializer( |
typeof(SerializableDictionary<TKey, TValue>), new XmlRootAttribute(DictionaryNodeName)) |
.Serialize(memoryStream, this); |
memoryStream.Seek(0, SeekOrigin.Begin); |
clone = (SerializableDictionary<TKey, TValue>) |
new XmlSerializer( |
typeof(SerializableDictionary<TKey, TValue>)) |
.Deserialize(writer); |
typeof(SerializableDictionary<TKey, TValue>), new XmlRootAttribute(DictionaryNodeName)) |
.Deserialize(memoryStream); |
} |
} |
/* cloning failed so return an empty dictionary */ |
@@ -66,64 +101,62 @@ |
return clone; |
} |
|
public XmlSchema GetSchema() |
{ |
return null; |
} |
#region Constants |
|
public void ReadXml(XmlReader reader) |
{ |
var keySerializer = new XmlSerializer(typeof(TKey)); |
var valueSerializer = new XmlSerializer(typeof(TValue)); |
public string DictionaryNodeName { get; set; } = "Dictionary"; |
public string ItemNodeName { get; set; } = "Item"; |
public string KeyNodeName { get; set; } = "Key"; |
public string ValueNodeName { get; set; } = "Value"; |
|
var wasEmpty = reader.IsEmptyElement; |
reader.Read(); |
#endregion |
|
if (wasEmpty) |
return; |
#region Constructors |
|
while (!reader.NodeType.Equals(XmlNodeType.EndElement)) |
{ |
reader.ReadStartElement("Item"); |
public SerializableDictionary() |
{ |
} |
|
reader.ReadStartElement("Key"); |
var key = (TKey) keySerializer.Deserialize(reader); |
reader.ReadEndElement(); |
public SerializableDictionary(IDictionary<TKey, TValue> dictionary) |
: base(dictionary) |
{ |
} |
|
reader.ReadStartElement("Value"); |
var value = (TValue) valueSerializer.Deserialize(reader); |
reader.ReadEndElement(); |
public SerializableDictionary(IEqualityComparer<TKey> comparer) |
: base(comparer) |
{ |
} |
|
Add(key, value); |
public SerializableDictionary(int capacity) |
: base(capacity) |
{ |
} |
|
reader.ReadEndElement(); |
reader.MoveToContent(); |
} |
reader.ReadEndElement(); |
public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) |
: base(dictionary, comparer) |
{ |
} |
|
public void WriteXml(XmlWriter writer) |
public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer) |
: base(capacity, comparer) |
{ |
var keySerializer = new XmlSerializer(typeof(TKey)); |
var valueSerializer = new XmlSerializer(typeof(TValue)); |
} |
|
foreach (var key in Keys) |
{ |
writer.WriteStartElement("Item"); |
#endregion |
|
writer.WriteStartElement("Key"); |
keySerializer.Serialize(writer, key); |
writer.WriteEndElement(); |
#region Private Properties |
|
writer.WriteStartElement("Value"); |
var value = this[key]; |
valueSerializer.Serialize(writer, value); |
writer.WriteEndElement(); |
protected XmlSerializer ValueSerializer |
=> valueSerializer ?? (valueSerializer = new XmlSerializer(typeof(TValue))); |
|
writer.WriteEndElement(); |
} |
} |
private XmlSerializer KeySerializer => keySerializer ?? (keySerializer = new XmlSerializer(typeof(TKey))); |
|
#endregion |
|
#region Private Members |
|
private XmlSerializer keySerializer; |
private XmlSerializer valueSerializer; |
|
#endregion |
} |
} |
/Collections/Specialized/MultiKeyDictionary.cs |
@@ -29,15 +29,8 @@ |
} |
} |
|
public new IEnumerable<V> Values |
{ |
get |
{ |
return from baseDict in base.Values |
from baseKey in baseDict.Keys |
select baseDict[baseKey]; |
} |
} |
public new IEnumerable<V> Values => |
base.Values.SelectMany(baseDict => baseDict.Keys, (baseDict, baseKey) => baseDict[baseKey]); |
|
public void Add(K1 key1, K2 key2, V value) |
{ |
@@ -46,10 +39,29 @@ |
this[key1][key2] = value; |
} |
|
public void Remove(K1 key1, K2 key2) |
{ |
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2)) |
return; |
this[key1].Remove(key2); |
Remove(key1); |
} |
|
public bool ContainsKey(K1 key1, K2 key2) |
{ |
return base.ContainsKey(key1) && this[key1].ContainsKey(key2); |
return ContainsKey(key1) && this[key1].ContainsKey(key2); |
} |
|
public bool TryGetValue(K1 key1, K2 key2, out V value) |
{ |
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2)) |
{ |
value = default(V); |
return false; |
} |
value = base[key1][key2]; |
return true; |
} |
} |
|
public class MultiKeyDictionary<K1, K2, K3, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, V>> |
@@ -67,8 +79,35 @@ |
|
public bool ContainsKey(K1 key1, K2 key2, K3 key3) |
{ |
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3); |
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3); |
} |
|
public void Add(K1 key1, K2 key2, K3 key3, V value) |
{ |
if (!ContainsKey(key1)) |
this[key1] = new MultiKeyDictionary<K2, K3, V>(); |
this[key1][key2, key3] = value; |
} |
|
public void Remove(K1 key1, K2 key2, K3 key3) |
{ |
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2, key3)) |
return; |
this[key1][key2].Remove(key3); |
this[key1].Remove(key2); |
Remove(key1); |
} |
|
public bool TryGetValue(K1 key1, K2 key2, K3 key3, out V value) |
{ |
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2, key3)) |
{ |
value = default(V); |
return false; |
} |
value = base[key1][key2, key3]; |
return true; |
} |
} |
|
public class MultiKeyDictionary<K1, K2, K3, K4, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, V>> |
@@ -86,7 +125,7 @@ |
|
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4) |
{ |
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4); |
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4); |
} |
} |
|
@@ -105,7 +144,7 @@ |
|
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5) |
{ |
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5); |
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5); |
} |
} |
|
@@ -125,7 +164,7 @@ |
|
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6) |
{ |
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6); |
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6); |
} |
} |
|
@@ -145,7 +184,7 @@ |
|
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7) |
{ |
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7); |
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7); |
} |
} |
|
@@ -165,7 +204,7 @@ |
|
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8) |
{ |
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8); |
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8); |
} |
} |
|
@@ -185,7 +224,7 @@ |
|
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9) |
{ |
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9); |
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9); |
} |
} |
|
@@ -209,7 +248,7 @@ |
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, |
K10 key10) |
{ |
return base.ContainsKey(key1) && |
return ContainsKey(key1) && |
this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9, key10); |
} |
} |
@@ -237,7 +276,7 @@ |
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, |
K10 key10, K11 key11) |
{ |
return base.ContainsKey(key1) && |
return ContainsKey(key1) && |
this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9, key10, key11); |
} |
} |