views:

100

answers:

4

This relates to this question, but this time I'm trying to work out how to serialize the dictionary. I have a class that inherits from Dictionary that I need to be able to serialize.

The Serialization methods look like this, basically the values collection from the dictionary are added to the list, which is serialized.

[Serializable]
public class Collection: SortedDictionary<Key, Node>, ISerializable
{  
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        List<Node> Nodes = new List<Node>();
        // The "Values" mentioned here is the SortedDictionary's Values collection
        Nodes.AddRange(Values);
        info.AddValue("Nodes", Nodes, Nodes.GetType());
    }

    public Collection(SerializationInfo info, StreamingContext context)
        : base(new Key.Comparer())
    {
        List<Node> SerValues = (List<Node>)info.GetValue("Nodes", typeof(List<Node>));
        foreach (Node ThisNode in SerValues)
        {
            // This add method has been extended so that it automatically generates the key.
            Add(ThisNode);
        }
    }
}

However when I the deserialize constructor is called, the list contains the right amount of values, just null values.

I suspect this is because the nodes haven't been deserialized yet (I know they can be serialized though), but then how can I fix this?

A: 

Did you try to use the [Serializable] attribute on your collection class? Was the result the same?

(why are you using ISerializable instead of the attribute?)

Markus Bruckner
I did use the [Serializable] attribute as well (I've added it to the post). I need the ISerializable so I can change how the Dictionary is serialized, since they can't normally be.
fneep
@fneep: What do you mean Dictionary cant be normally serialized?
leppie
That's weird, the internet had convinced me that dictionaries couldn't be serialized. Try googling "c# serialize dictionary". Even so, why doesn't this work?
fneep
A: 

If I'm not mistaken Dictionary is not serializable.

Yup: http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/5115ff4c-75a6-4a96-9c6b-b840e04c650d/

That also means that just inheriting from it and calling the child Serializable won't work. You'll have to use a different container - typically an array of a custom class Key/Value container - nothing too serious.

Doobi
That's what I've done. I implemented ISerializable and it serializes the dictionary as an array, and then re-adds the array elements to the dictionary in the constructor.
fneep
A: 

You may want to use a surrogate (implementing ISerializationSurrogate) instead of the above approach.

Have a look at http://msdn.microsoft.com/en-us/magazine/cc188950.aspx for an example.

Rodney Richardson
+1  A: 

Are you trying to Xml serialize/deserialize the dictionary? Is that why you're implememting the ISerializable interface and using the SerializationInfo instead?

Although the Xml serializer doesn't support the generic dictionary type, the DataContractSerializer does so maybe you could try using that instead? Failing that, here's an implementation of a Xml serializable dictionary which might worth a look at:

http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx

theburningmonk