Где лучше всего хранить временные данные десериализации?

Можно ли избежать добавления дополнительных полей в класс для хранения данных, которые необходимы только для десериализации / сериализации?

Предположим, у меня есть некоторый класс:

[Serializable]
class MyClass {
      [NonSerialized]
      NonSerializableDataType myField;

      SomeOtherDataType serializableTemporaryData;

      [OnSerializing]
      OnSerializing (StreamingContext context) {
          // build serializableTemporaryData from myField
      }

      [OnDeserialized]
      void OnDeserialized (StreamingContext context) {
         // build myField from serializableTemporaryData
      }
}

Есть ли способ избежать serializableTemporaryData поле в каждом объекте MyClass? Могу ли я, например, сделать его статичным (возможно, изменив мои методы On...)?

Ограничение: я не могу изменить реализацию NonSerializableDataType,

Пример: предположим, что myField содержит дескриптор ресурса. Затем при сериализации я должен сохранить некоторую информацию о том, как получить ресурс после десериализации, но я не могу сохранить сам дескриптор. Если я оберну дескриптор в другой класс, то я просто перенес проблему на класс-обертку - тогда я задам тот же вопрос для класса-обертки.

2 ответа

Решение

Если вам нужно контролировать процесс сериализации, вы должны реализовать ISerialization интерфейс.

[Serializable]
public class MyClass: ISerializable
{
    // As you are in control of serialization process now
    // [Serialized] and [NonSerialized] attributes are no longer required
    private NonSerializableDataType myField;

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // Create and populate your SomeOtherDataType local variable here, then push it into info variable
        // Or even better, dont create SomeOtherDataType, just put additional serialization data into info variable, for example:
        info.AddValue("URL", "http://this.way.com");
    }

    protected MyClass(SerializationInfo info, StreamingContext context)
    {
        // Dont forget to define constructor for deserialization purpose

        this.myField = new NonSerializableDataType(loadFromURL: (string)info.GetValue("URL", typeof(string)));
    }
}

Нет дополнительного класса только для данных сериализации, нет загрязнения полей. Единственная потенциальная проблема - следить за сериализуемыми данными, полученными из этого класса (перезаписать GetObjectData(...) если нужно).

Дополнительная информация: MSDN ISerializable

Существует концепция суррогатов сериализации, которая может помочь вам преодолеть трудности с SomeNonSerializableType, поскольку он был разработан именно по этой причине. Однако для этого требуется, чтобы у вас была возможность настроить суррогаты сериализации при создании средства форматирования. В противном случае вам нужно будет настроить процесс сериализации, выполнив ISerializable,

Другие вопросы по тегам