CSharp · Console
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections;
using System.Xml.Serialization;
using System.Xml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
class TestClass
{
internal static void Test()
{
HighLevelDictionary highLevelDictionary = new HighLevelDictionary();
LowLevelDictionary lowLevelDictionary = new LowLevelDictionary();
lowLevelDictionary.Add("S1", 0.00m);
lowLevelDictionary.Add("S2", 0.00m);
LowLevelDictionary lowLevelDictionary2 = new LowLevelDictionary();
lowLevelDictionary2.Add("S1", 4.00m);
lowLevelDictionary2.Add("S2", 4.00m);
highLevelDictionary.Add("One", lowLevelDictionary);
highLevelDictionary.Add("tWO", lowLevelDictionary2);
var result = BinaryFormatterHelper.ToBinary(highLevelDictionary);
var extraHighLevelDictionary = BinaryFormatterHelper.FromBinary<HighLevelDictionary>(result);
Console.WriteLine("Deserialized HighLevelDictionary contents: ");
Console.WriteLine(JsonConvert.SerializeObject(extraHighLevelDictionary, Newtonsoft.Json.Formatting.Indented));
if (!JToken.DeepEquals(JToken.FromObject(highLevelDictionary), JToken.FromObject(extraHighLevelDictionary)))
{
throw new InvalidOperationException("!JToken.DeepEquals(JToken.FromObject(highLevelDictionary), JToken.FromObject(extraHighLevelDictionary))");
}
else
{
Debug.WriteLine("Original and round-tripped dictionaries are equivalent");
}
}
}
[Serializable]
public class HighLevelDictionary : SerializableDictionary<string, LowLevelDictionary>
{
public HighLevelDictionary()
{
}
protected HighLevelDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
[Serializable]
public class LowLevelDictionary : SerializableDictionary<string, decimal>
{
protected LowLevelDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }
public LowLevelDictionary()
{
}
}
[Serializable()]
public class SerializableDictionary<TKey, TVal> : Dictionary<TKey, TVal>, IXmlSerializable
{
#region Constructors
public SerializableDictionary()
{
}
public SerializableDictionary(IDictionary<TKey, TVal> dictionary)
: base(dictionary)
{
}
public SerializableDictionary(IEqualityComparer<TKey> comparer)
: base(comparer)
{
}
public SerializableDictionary(int capacity)
: base(capacity)
{
}
public SerializableDictionary(IDictionary<TKey, TVal> dictionary, IEqualityComparer<TKey> comparer)
: base(dictionary, comparer)
{
}
public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
: base(capacity, comparer)
{
}
#endregion
#region ISerializable members
protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }
#endregion
#region Constants
private const string DictionaryNodeName = "Dictionary";
private const string ItemNodeName = "Item";
private const string KeyNodeName = "Key";
private const string ValueNodeName = "Value";
#endregion
#region IXmlSerializable Members
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
{
//writer.WriteStartElement(DictionaryNodeName);
foreach (KeyValuePair<TKey, TVal> 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
}
public class Program
{
public static void Main()
{
TestClass.Test();
}
}
public static partial class BinaryFormatterHelper
{
public static byte[] ToBinary<T>(T obj)
{
using (var stream = new MemoryStream())
{
new BinaryFormatter().Serialize(stream, obj);
return stream.ToArray();
}
}
public static T FromBinary<T>(byte[] data)
{
using (var stream = new MemoryStream(data))
{
var formatter = new BinaryFormatter();
var obj = formatter.Deserialize(stream);
if (obj is T)
return (T)obj;
return default(T);
}
}
}