Создание экземпляра унаследованного класса с использованием статического метода из базового класса - PullRequest
1 голос
/ 14 апреля 2010

У меня есть абстрактный базовый класс, из которого я получаю много унаследованных классов. Я хотел бы, чтобы статический член принимал строку, первый класс, который может анализировать строку (должен уметь только один из унаследованных классов) и возвращать экземпляр унаследованного класса.

Это то, чем я сейчас занимаюсь.

public static Epl2Command GenerateCommandFromText(string command)
{
    lock (GenerateCommandFromTextSyncRoot)
    {
        if (!Init)
        {
            Assembly a = Assembly.GetAssembly(typeof(Epl2Command));
            Types = new List<Type>(a.GetTypes());
            Types = Types.FindAll(b => b.IsSubclassOf(typeof(Epl2Command)));
            Init = true;
        }
    }
    Epl2Command ret = null;
    foreach (Type t in Types)
    {

        MethodInfo method = t.GetMethod("GenerateCommand", BindingFlags.Static | BindingFlags.Public);

        if (method != null)
            ret = (Epl2Command)method.Invoke(null, new object[] { command });
        if (ret != null)
            break;
    }
    return ret;
}

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

Есть ли способ заставить унаследованный класс реализовать свой собственный GenerateCommand(string)?

public static abstract Epl2Command GenerateCommand(string command) недопустимо c #. Или я забиваю гвоздь обувью, когда мне следует использовать молоток ; любой лучший способ сделать это фабрика класса будет оценена.

Ответы [ 2 ]

1 голос
/ 14 апреля 2010

C # не поддерживает статические интерфейсы, поэтому вы не можете определить метод статического компоновщика, как

public interface ICommand
{
    static ICommand CreateCommand(string command);
}

Я согласен с Кевином, что вам нужен шаблон Фабрики. Я сделаю еще один шаг и скажу, что вам нужен компоновщик для каждого типа команды. Как это

public interface ICommandBuilder
{
    bool CanParse(string input);
    ICommand Build(string input);
}

public interface ICommandBuilder<TCommand> : ICommandBuilder 
    where TCommand : ICommand
{
    TCommand Build(string input);
}

Тогда ваша фабрика может принять любую входную командную строку, запросить все сборщики, могут ли они проанализировать эту строку, и запустить Build на той, которая может.

public interface ICommandFactory
{
    ICommand Build(string input);
}

public class CommandFactory
{
    public ICommand Build(string input)
    {
        var builder = container.ResolveAll(typeof(ICommandBuilder))
            .First(x => x.CanParse(input));
        return builder.Build(input);
    }
}
0 голосов
/ 14 апреля 2010

То, к чему вы стремитесь, - это фабричный метод:

http://www.dofactory.com/Patterns/PatternFactory.aspx

Вот ссылка, как это реализовать.

...