简体   繁体   English

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

[英]How to create a base class with static factory method in C#?

I have need to use one of two custom file readers classes; 我需要使用两个自定义文件阅读器类之一; one to read a fixed width file and one for a CSV file. 一个读取固定宽度的文件,一个读取CSV文件。 Each of these readers will have certain properties, etc. I want to use factory methods and have private constructors so I can run some business logic before creating the objects. 这些阅读器中的每一个都将具有某些属性,等等。我想使用工厂方法并拥有私有构造函数,因此我可以在创建对象之前运行一些业务逻辑。

EDIT: better examples 编辑:更好的例子

//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();
    }
}

What I want to be able to do is define a base class, then override the factory. 我想要做的是定义一个基类,然后覆盖工厂。 I guess the problem is that a static class belongs to the base CLASS, so can never be overriden, even though they ARE inherited. 我想问题是静态类属于基本CLASS,因此即使继承了它们也不能覆盖。 This code works 此代码有效

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

EDIT: To clarify further, what I'm trying to do is put some common functionality in my base class, but define an interface for my file-format-specific methods. 编辑:为了进一步阐明,我想做的是在我的基类中放一些通用功能,但是为我的文件格式专用方法定义了一个接口。 Some of the methods are common, but the business logic for the constructor(s) is file format specific. 某些方法很常见,但构造函数的业务逻辑是文件格式特定的。 My code above works, but it seems to me it would be better to mark the base class factory method as virtual, and the derived class factory method as "override". 上面的代码可以正常工作,但是在我看来,将基类工厂方法标记为虚拟,将派生类工厂方法标记为“覆盖”会更好。

I tried to do this, but got "A static member cannot be marked as override, virtual, or abstract". 我试图这样做,但是得到了“静态成员无法标记为替代,虚拟或抽象”。

What's the right way to achieve my goals? 什么是实现我目标的正确方法?

First, explaining your specific error message: you cannot inherit static members because they belong to the type being defined, not the instance of the type. 首先,解释您的特定错误消息:您不能继承静态成员,因为它们属于所定义的类型,而不是该类型的实例。 Inheritance modifiers such as override, virtual, and abstract do not apply to static members. 继承修饰符(例如,override,virtual和abstract)不适用于静态成员。

Second: 第二:

Typically when you follow a factory pattern, you have a factory class whose job is to instantiate concrete classes and return those instances cast as a base class or interface. 通常,当您遵循工厂模式时,就有一个工厂类,其工作是实例化具体类并返回那些转换为基类或接口的实例。 Details vary as to how the factory chooses which concrete class to instantiate, and I won't get into that, but at the fundamental level, that's what a factory does. 关于工厂如何选择要实例化的具体类的细节有所不同,我将不予讨论,但是从根本上讲,这就是工厂的工作。

So in order to create a factory pattern using the example you provided, you'll need at least four types, which, following your example, could probably be named ReaderBase , ReaderFactory , CsvReader , and FixedWidthReader . 因此,为了使用提供的示例创建工厂模式,您至少需要四种类型,在您的示例之后,这些类型可能被命名为ReaderBaseReaderFactoryCsvReaderFixedWidthReader Rather than ReaderBase , you might consider IReader -- the choice depends on whether your abstract class pre-implements any functionality that is shared across all Readers . 您可以考虑使用IReader而不是ReaderBase ,它的选择取决于您的抽象类是否预先实现了所有Readers共享的任何功能。

CsvReader and FixedWidthReader inherit from either IReader or ReaderBase , and ReaderFactory has at least one method called, for example, InstantiateReader , which returns an IReader or ReaderBase . CsvReaderFixedWidthReader继承自IReaderReaderBase ,并且ReaderFactory至少具有一个称为InstantiateReader ,该方法返回IReaderReaderBase InstantiateReader does the work of determining whether to instantiate a CsvReader or a FixedWidthReader , based on some external criteria. InstantiateReader会根据一些外部条件来确定是实例化CsvReader还是FixedWidthReader

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM