Question39098498 BinaryFormatter and ISerializable

CSharp · Console

/Program.cs

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);
            }
        }
    }
;