Question

I'm trying to serialize Dictionary<int, int> as Dictionary<string, string>.

So I've created Test2 type from Dictionary<int, int> as follows:

    [Serializable]
    internal sealed class Test2 : Dictionary<int, int>
    {
        internal Test2()
        {
        }

        private Test2(SerializationInfo info, StreamingContext context)
        {
            var data = (Dictionary<string, string>)
                       info.GetValue("data", typeof(Dictionary<string, string>));
            foreach (var item in data)
                Add(int.Parse(item.Key), int.Parse(item.Value));
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            var data = new Dictionary<string, string>();
            foreach (var item in this)
                data[item.Key.ToString()] = item.Value.ToString();
            info.AddValue("data", data, typeof(Dictionary<string, string>));
        }
    }

and use the following code to test the serialization:

        var test2 = new Test2 {{10, 10}};
        var formatter = new BinaryFormatter();
        using (var stream = new MemoryStream())
        {
            formatter.Serialize(stream, test2);
            stream.Position = 0;
            var clone = (Test2) formatter.Deserialize(stream);
        }

For some reason the clone does not contains any data (Count eq to 0).

Update:

"int" and "string" are here only for testing. In the real application I use something like Primary Key instead of string and big object instead of int and the serialized array contains relations between them. By cutting down the unrelated code and replacing the types I end up with with the example above.

I can only use .NET framework features.

Was it helpful?

Solution

There is no need for you to convert integers to strings during serialization or define your own serializable class - the framework takes care of that for you. This code (modified from this question) will do what you want just fine:

var test2 = new Dictionary<int, int> { { 10, 10 } } ;
var formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
    formatter.Serialize(stream, test2);
    stream.Position = 0;
    var clone = (Dictionary<int, int>) formatter.Deserialize(stream);
}

I'm uncertain why your original code didn't work, but I think it has something to do with the SerializationInfo collection being unable to serialize/deserialize dictionaries correctly. I replaced your class with this code that uses List<Tuple<string,string>> in place of Dictionary<string,string> and it works fine:

[Serializable]
internal sealed class Test2 : Dictionary<int, int>
{
    internal Test2()
    {
    }

    private Test2(SerializationInfo info, StreamingContext context)
    {
        var data = (List<Tuple<string, string>>)
                   info.GetValue("data", typeof(List<Tuple<string, string>>));
        foreach (var item in data)
            Add(int.Parse(item.Item1), int.Parse(item.Item2));
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        var data = new List<Tuple<string, string>>();
        foreach (var item in this)
            data.Add(Tuple.Create(item.Key.ToString(), item.Value.ToString()));
        info.AddValue("data", data, typeof(List<Tuple<string, string>>));
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top