【问题标题】:How to create instances of type declarations?如何创建类型声明的实例?
【发布时间】:2019-02-24 03:49:16
【问题描述】:

我想将类声明存储在结构中,然后从该类中实例化新对象,但我遇到了一些障碍。我知道如何用其他几种语言做到这一点,但在 C# 中我还没有取得任何成功。

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

class FooCommand : Command
{
}

class ListCommand : Command
{
}

现在我想要一个存储一些数据的结构和一个命令子类类引用:

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

我已经检查了page 中有关如何实例化类型的方法,但由于Type 不代表任何具体的类,我想知道如何让commandClass 实例化为其类型的正确对象?在这种情况下将类声明存储为结构中的Type 是否正确,还是有更好的方法?

【问题讨论】:

  • 使用 Activator.CreateInstance docs.microsoft.com/en-us/dotnet/api/…
  • 这甚至可以编译给你吗?你必须写typeof(FooCommand)
  • @PawełAudionysos 这一部分是我从脑海中编写的伪代码。我想我找到了我需要的东西:var instance = Activator.CreateInstance(commandClass); var obj = instance as Command; if (obj != null) var command = obj;
  • 将其添加为答案 :) 并非所有偶然发现此问题的人都会阅读 cmets。
  • 这里通常使用Func&lt;Command&gt; 而不是Type。这避免了 Activator.CreateInstance 的开销,并且还允许您拥有没有无参数构造函数的命令。 Func&lt;Command&gt; Factory 然后Factory = () =&gt; new FooCommand() 分配它,.Factory() 调用它并创建新的Command

标签: c# types instance


【解决方案1】:

你必须用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");

【讨论】:

  • 感谢有关使用 typeof 的提示!
猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2023-01-09
相关资源
最近更新 更多