Я пытаюсь сделать класс, который я написал, сериализуемым. Он содержит несколько статических полей только для чтения, которые никогда не меняются после создания, поэтому их не нужно сериализовать. У меня проблемы с поиском способа переустановить их после десериализации, что не ослабляет доступ в базовом классе. Вот упрощенный пример, начиная с несериализуемой базы и производного класса:
internal abstract class MyBase
{
private readonly List<int> myIntList = new List<int> ();
internal MyBase (List<int> anIntList)
{
this.myIntList = anIntList;
}
}
Производному классу не требуется доступ к списку, поэтому поле может быть доступно только для чтения в базовом классе, а производный класс устанавливает его следующим образом:
internal sealed class MyDerived : MyBase
{
private static readonly List<int> derivedIntList = new List<int> { 1, 2, 3 };
internal MyDerived () : base (MyDerived.derivedIntList)
{
}
}
Теперь я хочу сделать мой производный класс сериализуемым. Поскольку содержимое списка не меняется, их не нужно сериализовать, поэтому я просто помещаю атрибут DataContract в оба класса.
Я сериализирую производный класс на диск следующим образом:
private static void SeralizeDerived (string path)
{
MyDerived derived = new MyDerived ();
DataContractSerializer serializer = new DataContractSerializer (typeof (MyDerived));
using (FileStream stream = new FileStream (path, FileMode.Create))
{
serializer.WriteObject (stream, derived);
stream.Flush ();
}
}
и десериализовать его так:
private static void DeserializeDerived (string path)
{
DataContractSerializer serializer = new DataContractSerializer (typeof (MyDerived));
using (FileStream stream = new FileStream (path, FileMode.Open, FileAccess.Read))
{
MyDerived derived = serializer.ReadObject (stream) as MyDerived;
// debugger shows derived.myIntList as null, as expected
}
}
Согласно комментарию в DeserializeDerived, значение output.myIntList равно нулю. Это не удивительно для меня - я не просил его сериализовать, и я ничего не сделал, чтобы воссоздать его после десериализации.
Проблема заключается в следующем: единственный известный мне способ исправить это - изменить доступ к myIntList, чтобы сделать его защищенным, и иметь метод OnDeserialized в классе MyDerived, который (пере) устанавливает myIntList:
private void ReInitialize ()
{
base.myIntList = MyDerived.derivedIntList;
}
[OnDeserialized]
private void OnDeserialized (StreamingContext context)
{
this.ReInitialize ();
}
internal MyDerived () : base ()
{
this.ReInitialize ();
}
Это кажется неправильным - я не хочу ослаблять доступ к членам базового класса, и инициализация полевых элементов в производном конструкторе более подвержена ошибкам. Вопрос в том, как сохранить ту же защиту членов, но при этом поддерживать сериализацию?