Где лучше всего хранить временные данные десериализации?
Можно ли избежать добавления дополнительных полей в класс для хранения данных, которые необходимы только для десериализации / сериализации?
Предположим, у меня есть некоторый класс:
[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
,