Как создать базовый класс со статическим методом фабрики в C #? - PullRequest
1 голос
/ 21 октября 2011

Мне нужно использовать один из двух пользовательских классов для чтения файлов;один для чтения файла фиксированной ширины и один для файла 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 Ответ

5 голосов
/ 21 октября 2011

Во-первых, объясняя ваше конкретное сообщение об ошибке: вы не можете наследовать статические члены, потому что они принадлежат определенному типу, а не экземпляру типа. Модификаторы наследования, такие как override, virtual и abstract, не применяются к статическим элементам.

Второй:

Как правило, когда вы следуете фабричному шаблону, у вас есть фабричный класс, задачей которого является создание экземпляров конкретных классов и возврат этих экземпляров, приведенных в качестве базового класса или интерфейса. Детали варьируются в зависимости от того, как фабрика выбирает конкретный класс для создания экземпляра, и я не буду вдаваться в подробности, но на фундаментальном уровне это именно то, что делает фабрика.

Таким образом, чтобы создать фабричный шаблон с использованием предоставленного вами примера, вам понадобится как минимум четыре типа, которые, следуя вашему примеру, могут быть названы ReaderBase, ReaderFactory, CsvReader и FixedWidthReader. Вместо ReaderBase вы можете рассмотреть IReader - выбор зависит от того, реализует ли ваш абстрактный класс какие-либо функции, общие для всех Readers.

CsvReader и FixedWidthReader наследуются от IReader или ReaderBase, а ReaderFactory имеет как минимум один вызванный метод, например, InstantiateReader, который возвращает IReader или ReaderBase. InstantiateReader выполняет работу по определению, следует ли создавать экземпляр CsvReader или FixedWidthReader, основываясь на некоторых внешних критериях.

...