Я только что заметил странное поведение в двоичной сериализации: когда я десериализую словарь в своем классе и пытаюсь сразу добавить что-то к нему, я получаю сообщение об ошибке, потому что оно не полностью инициализировано:
[Serializable]
class Foo : ISerializable
{
public Dictionary<int, string> Dict { get; private set; }
public Foo()
{
Dict = new Dictionary<int, string>();
}
public Foo(SerializationInfo info, StreamingContext context)
{
Dict = (Dictionary<int, string>)info.GetValue("Dict", typeof(Dictionary<int, string>));
Dict.Add(99, "test"); // Error here
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Dict", Dict);
}
}
Вкл.В строке, где я добавляю данные в словарь, я получаю NullReferenceException
, но свойство Dict
не равно нулю: оно создается, но не инициализируется (все его поля равны 0 или нулю).Я подозреваю, что он был создан только с FormatterServices.GetUninitializedObject
, но еще не десериализован.
Я понимаю, что на данный момент, возможно, не предполагается, что будет полностью инициализирован.Поэтому я попробовал другой подход, реализовав интерфейс IDeserializationCallback
.MSDN говорит:
Реализация текущего интерфейса как часть поддержки метода, который вызывается, когда десериализация графа объектов завершена.
Если объект должен выполнить код на своих дочерних объектах, он может отложить это действие, реализовать IDeserializationCallback и выполнить код только при его повторном вызове на этом интерфейсе
Такпохоже, это именно то, что мне нужно, и я ожидал, что мой словарь будет полностью инициализирован при вызове OnDeserialization
... Но я получаю ту же ошибку!
[Serializable]
class Foo : IDeserializationCallback
{
public Dictionary<int, string> Dict { get; private set; }
public Foo()
{
Dict = new Dictionary<int, string>();
}
public void OnDeserialization(object sender)
{
Dict.Add(99, "test"); // Error here
}
}
Так как IDeserializationCallback
предназначенный для выполнения кода на дочерних объектах, я ожидал бы, что дочерние объекты будут полностью инициализированы на этом этапе.Обратите внимание, что если я вызываю OnDeserialize
вручную в словаре, он работает нормально, но почему-то я не думаю, что должен это делать ...
Это поведение нормально?Кто-нибудь может объяснить, что здесь происходит?