Как создать экземпляры объявлений типов? - PullRequest
0 голосов
/ 24 февраля 2019

Я хочу сохранить объявление класса в структуре, а затем создать новые объекты из этого класса, но я сталкиваюсь с несколькими препятствиями.Я знаю, как это сделать на нескольких других языках, но в C # я пока не добился успеха.

abstract class Command
{
    // Base class for all concrete command classes.
}

class FooCommand : Command
{
}

class ListCommand : Command
{
}

Теперь я хочу иметь структуру, которая хранит некоторые данные, и класс подкласса Command ref:

struct CommandVO
{
    string trigger;
    string category;
    Type commandClass;
}

Где-то еще позже я хочу извлечь структуры VO из словаря и создать конкретные объекты команд:

var commandMap = new Dictionary<string, CommandVO?>(100);
commandMap.Add("foo", new CommandVO
{
    trigger = "foo", category = "foo commands", commandClass = FooCommand
});
commandMap.Add("list", new CommandVO
{
    trigger = "list", category = "list commands", commandClass = ListCommand
});

...

var commandVO = commandMap["foo"];
if (commandVO != null)
{
    var commandClass = commandVO.Value.commandClass;
    // How to instantiate the commandClass to a FooCommand object here?
}

Я проверил эту страницу для методов о том, как создавать экземпляры типов, но поскольку Type не представляет какой-либо конкретный класс, мне интересно, как я могу получить commandClass, чтобы создать экземпляр для надлежащего объекта его типа?И правильно ли в этом случае хранить объявления классов как Type в структуре или есть лучший подход?

1 Ответ

0 голосов
/ 24 февраля 2019

Вы должны обернуть тип с помощью typeof():

var commandMap = new Dictionary<string, CommandVO?>(100);
commandMap.Add("foo", new CommandVO {
    trigger = "foo", category = "foo commands", commandClass = typeof(FooCommand)
});

Вы можете написать метод расширения следующим образом:

internal static class CommandHelper {

    internal static Command createCommand(this Dictionary<string, CommandVO?> d, string name) {
        if (!d.ContainsKey(name)) return null;
        return Activator.CreateInstance(d[name]?.commandClass) as Command;
    }

}

Чем вы можете получить свой экземпляр Cammand:

var instance = commandMap.createCommand("foo");
...