我正在尝试使我编写的类可序列化。它包含几个静态只读字段,这些字段在构造后不会更改,因此不需要序列化。我很难找到一种方法,以便在反序列化之后重新设置它们,这不会削弱对基类的访问。这是一个简化的示例,从不可序列化的基类和派生类开始:
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中的注释,derived.myIntList的值为null。这对我来说并不奇怪-我没有要求它进行序列化,并且在反序列化之后我没有做任何事情来重新创建它。
问题是这样的:我知道要解决此问题的唯一方法是更改对myIntList的访问权限以使其受到保护,并在MyDerived类中具有一个(重新)设置myIntList的OnDeserialized方法:
private void ReInitialize ()
{
base.myIntList = MyDerived.derivedIntList;
}
[OnDeserialized]
private void OnDeserialized (StreamingContext context)
{
this.ReInitialize ();
}
internal MyDerived () : base ()
{
this.ReInitialize ();
}
这感觉是错误的-我不想削弱对基类成员的访问,并且在派生的构造函数中逐字段初始化成员比较容易出错。问题是:如何保持相同的成员保护但仍支持序列化?
答案 0 :(得分:0)
将静态列表传递给基类构造函数对我来说很奇怪。我要说的是继承有问题。
如果您仍然想使用继承,请尝试使用抽象属性:
public abstract class Data
{
public abstract int[] list { get;}
}
public class Data2 : Data
{
private static readonly int[] arr = new[] {1,2,3};
public override int[] list { get => arr; }
}