Как изменить порядок десериализации с помощью BinaryFormatter в C #? - PullRequest
5 голосов
/ 28 октября 2009

Допустим, у меня есть classA, который содержит classB и оба [Serializable].

Я предполагал, что при десериализации класс B будет десериализован первым.

Однако это не тот случай, поскольку я могу подтвердить это, просто войдя в систему, когда были вызваны все методы [OnDeserialized].

Теперь у меня есть следующая проблема:

После того, как десериализация класса A завершена, он должен сам себя настроить, используя значения из classB. К сожалению, на этом этапе classB еще не десериализован, поэтому classA неправильно настроен.

Моя проблема была бы решена, если бы я мог заставить BinaryFormatter десериализовать classB перед classA или разрешить граф объектов снизу вверх вместо сверху вниз.

Другим очевидным решением было бы заставить classB инициировать событие, когда оно десериализовано, и затем настроить classA, но я хочу держаться подальше от этого не элегантного обходного пути.

Так что я был бы признателен, если бы кто-нибудь знал о лучшем решении.

Ответы [ 4 ]

3 голосов
/ 28 октября 2009

Если вам нужно явно контролировать порядок сериализации и десериализации ваших объектов, я предлагаю вам реализовать интерфейс ISerializable для A:

public class ClassA : ISerializable
{
    private ClassB _dependency;

    public ClassA(SerializationInfo information, StreamingContext context)
    {
        _dependency 
            = (ClassB)information.GetValue("_dependency", typeof(ClassB));

        // TODO: Get other values from the serialization info.
        // TODO: Set up stuff from dependent object.
    }

    public SerializationInfo GetObjectData()
    {
        information.AddValue("_dependency", _dependency, typeof(ClassB));

        // TODO: Add other fields to the serialization info.
    }
}
1 голос
/ 07 сентября 2010

Вы можете заставить classA реализовать интерфейс IDeserializationCallback. Его метод OnDeserialization будет вызываться только после десериализации графа объекта весь , включая объект classB.

1 голос
/ 28 октября 2009

Я бы предложил просто использовать метод, помеченный [OnDeserialized], для обработки любой инициализации после сериализации, которая вам требуется, и не заботиться о порядке, в котором они десериализованы.

0 голосов
/ 07 сентября 2010

Эти два шага могут помочь:

  1. Сделать метод [OnDeserialized] класса B безопасным для многократного вызова.
  2. В методе [OnDeserialized] класса A явным образом вызовите метод [OnDeserialized] для содержащегося объекта classB.

В конечном итоге BinaryFormatter вызовет метод [OnDeserialized] для объекта classB, но шаг 1 сделает это безопасным.

...