保留限制性访问修饰符并使 class 可序列化

Preserving restrictive access modifiers and making a class serializable

我正在尝试制作一个 class 我写的可序列化的。它包含几个构造后永远不会改变的静态只读字段,因此不需要序列化。我很难找到一种在反序列化后不会削弱基础 class 中的访问权限的方法来重新设置它们。这是一个简化的示例,从不可序列化的基础开始并派生 class:

internal abstract class MyBase
{
    private readonly List<int> myIntList = new List<int> ();

    internal MyBase (List<int> anIntList)
    {
        this.myIntList = anIntList;
    }
}

派生class不需要访问列表,所以该字段在基class中可以是private readonly,派生class这样设置:

internal sealed class MyDerived : MyBase
{
    private static readonly List<int> derivedIntList = new List<int> { 1, 2, 3 };

    internal MyDerived () : base (MyDerived.derivedIntList)
    {
    }
}

现在我想让派生的 class 可序列化。由于列表内容没有改变,因此不需要序列化它们,所以我只是在两个 classes.

上都放置了一个 DataContract 属性

我将派生的 class 序列化到磁盘,如下所示:

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 class 中使用 OnDeserialized 方法(重新)设置 myIntList:

private void ReInitialize ()
{
    base.myIntList = MyDerived.derivedIntList;
}

[OnDeserialized]
private void OnDeserialized (StreamingContext context)
{
    this.ReInitialize ();
}

internal MyDerived () : base ()
{
    this.ReInitialize ();
}

这感觉不对——我不想弱化对基 class 成员的访问,在派生构造函数中逐字段初始化成员更容易出错。问题是:如何在保持会员保护不变的同时还支持连载?

将静态列表传递到基础 class 构造函数对我来说很奇怪。我会说这里的继承有问题。

如果你仍然想使用抽象的继承尝试方法 属性:

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; }
}