【发布时间】:2019-11-18 20:25:09
【问题描述】:
我正在尝试使我编写的类可序列化。它包含几个静态只读字段,在构建后永远不会改变,因此它们不需要序列化。我很难找到一种在反序列化后重新设置它们的方法,这种方法不会削弱基类中的访问。这是一个简化的示例,从不可序列化的基类和派生类开始:
internal abstract class MyBase
{
private readonly List<int> myIntList = new List<int> ();
internal MyBase (List<int> anIntList)
{
this.myIntList = anIntList;
}
}
派生类不需要访问列表,所以该字段在基类中可以是private readonly,派生类这样设置:
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 类中有一个 OnDeserialized 方法(重新)设置 myIntList:
private void ReInitialize ()
{
base.myIntList = MyDerived.derivedIntList;
}
[OnDeserialized]
private void OnDeserialized (StreamingContext context)
{
this.ReInitialize ();
}
internal MyDerived () : base ()
{
this.ReInitialize ();
}
这感觉不对——我不想削弱对基类成员的访问,并且在派生构造函数中逐字段初始化成员更容易出错。问题是:如何保持相同的成员保护但仍支持序列化?
【问题讨论】:
-
如果是关于 Json 反序列化,可以使用构造函数反序列化:stackoverflow.com/questions/23017716/…(对于 XML,没有构造函数反序列化 AFAIK)
标签: c# serialization encapsulation access-specifier