如何覆盖子类中的静态类工厂方法

How to override static, factory-like method in subclasses

问题:

基class中的静态方法不能被覆盖,所以我不能编译这段代码(如果可以的话,我的设计就解决了):

public abstract class ParametersBase
{
    public static abstract ParametersBase CreateDefault();  // THIS DOES NOT COMPILE!
}

public abstract class ParametersXml<T> where T : ParametersBase
{
    public static T LoadOrDefault(string fname)
    {
        System.Threading.Thread.CurrentThread.CurrentCulture =
            System.Globalization.CultureInfo.InvariantCulture;

        T result;

        var serializer = new XmlSerializer(typeof(T));
        FileStream fs;

        try
        {
            using (fs = new FileStream(fname, FileMode.Open, FileAccess.Read))
                result = (T)serializer.Deserialize(fs);
        }
        catch (InvalidOperationException)
        {
            result = (T)typeof(T).GetMethod("CreateDefault").Invoke(null, new object[] { });
            using (fs = new FileStream(fname, FileMode.Create, FileAccess.Read))
                serializer.Serialize(fs, result);
        }

        return result;
    }
}

上下文:

我正在尝试使用泛型在一组表示参数组的子classes 中实现简单的XML持久性:

我什至不确定这些应该是正确的合作,我的意思是,每个 ParameterBase 都需要 "wrapped" 由 ParametersXml<>,而也许正确的事情是通过继承将持久性代码 封装在 基础 class 中...

这是一个好方法吗?我错过了什么吗?

只是为了详细说明评论中发生的事情。

static 方法标记为 abstract 会产生编译时错误。主要是因为你不能将一般意义上的多态应用于抽象方法(永远不会有虚方法调用)。

在此实例中需要的是不将方法标记为 static。现在由此产生的问题是,不能确定可以获取T的一个实例。然而,这可以通过进一步约束 T 来改变,使构造函数不带参数,方法是将 class 定义更改为:

public abstract class ParametersXml<T> where T : ParametersBase, new()

现在 catchLoadOrDefault 中可以说:

result = new T().CreateDefault();

请注意,这也更加简洁,并且避免了反射和脏类型转换的使用。

编辑: 更进一步

正如@AlexeiLevenkov 所指出的——假设 CreateDefault 应该是 return 它自己类型的实例,并且无参数构造函数在其默认设置中设置 T状态。甚至可以完全消除对 CreateDefault 的需要,只需将无参数构造函数用作 CreateDefault,从而将 catch 处理程序中的行更改为:

result = new T();