如何在C#中使用静态工厂方法创建基类?

时间:2011-10-21 18:02:40

标签: c# static factory

我需要使用两个自定义文件读取器类之一;一个读取固定宽度文件,一个读取CSV文件。这些读者中的每一个都具有某些属性等。我想使用工厂方法并拥有私有构造函数,因此我可以在创建对象之前运行一些业务逻辑。

编辑:更好的例子

//simple class with it's own factory method
class Class1
{
    private Class1()
    {
        //constructor code
    }
    public static Class1 CreateClass()
    {
        //do some business logic here
        return new Class1();
    }
}

我希望能够做的是定义一个基类,然后覆盖工厂。我想问题是静态类属于基类CLASS,所以永远不能被覆盖,即使它们是继承的。此代码有效

public class BaseClass
{
    //some common properties / fields here
    public string SomeField;

    //some common methods here

    //empty constructor
    protected BaseClass() { }

    //cannot have a virtual static class!  
    //Would really like to make this a virtual method
    public static BaseClass CreateClass() 
    {
        throw new NotImplementedException("BaseClass is meant to be derived");
    }

    public static string DoCommonStaticThing(){
        return "I don't know why you'd ever do this"; 
    }
}

public class DerivedClass1 : BaseClass
{
    //private constructor
    private DerivedClass1() {}

    //concrete factory method
    //would really like to say "override" here
    public static BaseClass CreateClass()
    {
        DerivedClass1 d1 = new DerivedClass1();
        d1.SomeField = "I'm a derived class\r\n" + DoCommonStaticThing();
        return d1;
    }
}

编辑:为了进一步澄清,我正在尝试做的是在我的基类中添加一些常用功能,但为我的特定于文件格式的方法定义一个接口。某些方法很常见,但构造函数的业务逻辑是特定于文件格式的。我上面的代码可以工作,但在我看来,最好将基类工厂方法标记为虚拟,将派生类工厂方法标记为“覆盖”。

我尝试这样做,但得到“静态成员不能被标记为覆盖,虚拟或抽象”。

实现目标的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

首先,解释您的特定错误消息:您不能继承静态成员,因为它们属于要定义的类型,而不属于该类型的实例。诸如override,virtual和abstract之类的继承修饰符不适用于静态成员。

第二:

通常,当您遵循工厂模式时,您有一个工厂类,其作用是实例化具体类并返回转换为基类或接口的实例。关于工厂如何选择实例化的具体类别的细节各不相同,我不会深入研究,但从根本上讲,这就是工厂所做的事情。

因此,为了使用您提供的示例创建工厂模式,您至少需要四种类型,按照您的示例,可能会将其命名为ReaderBaseReaderFactory,{{ 1}}和CsvReader。而不是FixedWidthReader,您可能会考虑ReaderBase - 选择取决于您的抽象类是否预先实现了在所有IReader中共享的任何功能。

ReadersCsvReader继承自FixedWidthReaderIReader,而ReaderBase至少有一种方法,例如ReaderFactory ,返回InstantiateReaderIReaderReaderBase根据一些外部标准执行确定是否实例化InstantiateReaderCsvReader的工作。