Denis
Denis

Reputation: 344

Cannot deserialize ObservableDictionary

I use ObservableDictionary class from Dr.WPF and I need to serialize and deserialize this collection. Serialization goes well, but when I try to deserialize it throw an exception:

$exception  {"Object reference not set to an instance of an object."}   System.Exception {System.NullReferenceException}
StackTrace  "   at EngineConfigurationManager.ObservableDictionary.ObservableDictionary`2.AddEntry(TKey key, TValue value) in d:\\Доки\\Editor\\EngineConfigurationManager\\EngineConfigurationManager\\ObservableDictionary\\ObservableDictionary.cs:line 196\r\n   at EngineConfigurationManager.ObservableDictionary.ObservableDictionary`2.OnDeserialization(Object sender) in d:\\Доки\\Editor\\EngineConfigurationManager\\EngineConfigurationManager\\ObservableDictionary\\ObservableDictionary.cs:line 592\r\n   at System.Runtime.Serialization.ObjectManager.RaiseDeserializationEvent()\r\n   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)\r\n   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)\r\n   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)\r\n   at EngineConfigurationManager.ConfigClasses.Camera.CameraConfigurationManager.Load() in d:\\Доки\\Editor\\EngineConfigurationManager\\EngineConfigurationManager\\ConfigClasses\\Camera\\CameraConfigurationManager.cs:line 936" string

I tried to debug mentioned method

public virtual void OnDeserialization(object sender)
    {
        if (_siInfo != null)
        {
            Collection<DictionaryEntry> entries = (Collection<DictionaryEntry>)
                _siInfo.GetValue("entries", typeof(Collection<DictionaryEntry>));
            foreach (DictionaryEntry entry in entries)
                AddEntry((TKey)entry.Key, (TValue)entry.Value);
        }
    }

protected KeyedDictionaryEntryCollection<TKey> _keyedEntryCollection;

protected virtual bool AddEntry(TKey key, TValue value)
    {
        _keyedEntryCollection.Add(new DictionaryEntry(key, value));
        return true;
    }

but I cannot find any error: key and value are not empty or null.

Does anyone knows what is the reason of the problem?

Edit: There are few constructors in ObservableDictionary class, but I think deserialization doesnt invoke any of them.

public ObservableDictionary()
    {
        _keyedEntryCollection = new KeyedDictionaryEntryCollection<TKey>();
    }

    public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
    {
        _keyedEntryCollection = new KeyedDictionaryEntryCollection<TKey>();

        foreach (KeyValuePair<TKey, TValue> entry in dictionary)
            DoAddEntry((TKey)entry.Key, (TValue)entry.Value);
    }

    public ObservableDictionary(IEqualityComparer<TKey> comparer)
    {
        _keyedEntryCollection = new KeyedDictionaryEntryCollection<TKey>(comparer);
    }

    public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
    {
        _keyedEntryCollection = new KeyedDictionaryEntryCollection<TKey>(comparer);

        foreach (KeyValuePair<TKey, TValue> entry in dictionary)
            DoAddEntry((TKey)entry.Key, (TValue)entry.Value);
    }

I can make so:

protected KeyedDictionaryEntryCollection<TKey> _keyedEntryCollection = new        KeyedDictionaryEntryCollection<TKey>();

but I don`t think this is correct way. I deserialize collection this way: CombinedCameraContainer = (ObservableDictionary) binaryFormatter.Deserialize(fs);

Is there something you can suggest me in this situation?

Upvotes: 0

Views: 410

Answers (2)

Martin Liversage
Martin Liversage

Reputation: 106826

Based on your comments this is the line that throws the exception:

_keyedEntryCollection.Add(new DictionaryEntry(key, value));

The only reference that is dereferenced in that line is _keyedEntryCollection so that must be null.

To solve your problem you need to initialize the _keyedEntryCollection field when the instance is constructed:

protected KeyedDictionaryEntryCollection<TKey> _keyedEntryCollection
  = new KeyedDictionaryEntryCollection<TKey>();

Or you can perform the initialization in an appropriate constructor instead.

Upvotes: 1

Boluc Papuccuoglu
Boluc Papuccuoglu

Reputation: 2346

The problem is that most probably ObservableDictionary uses KeyValuePair as its underlying item type. This class is immutable so it cannot be constructed with a parameterless constructor and then have its Key and Value members set. So, it cannot be used with most deserializers which expect such behavior.

Upvotes: 0

Related Questions