创建方法的 DeclaringType 实例:Activator.CreateInstance

Create an instance of the DeclaringType of a method: Activator.CreateInstance

我又一次在反思中挣扎。我只是给你一段我的调试器没有咬到的代码:

public bool HandleCommand(string command)
        {
            
            MethodInfo m = methods.FirstOrDefault(t => t.GetCustomAttribute<CommandAttribute>().Name == command);
            ICommandSet set =(m.DeclaringType)Activator.CreateInstance(m.DeclaringType);
            m?.Invoke(set, null);
            return true;
        }

基本上,此代码位于名为 CommandHandler 的 class 中。当它被构造时,它会遍历执行程序集中实现特定接口的所有类型,并将它们的所有方法存储在 List 中,这些方法附加了 CustomAttribute;出于这个问题的目的,我只是假设一切都在那里工作。该属性只有一个 属性:

[AttributeUsage(AttributeTargets.Method)]
    public class CommandAttribute : Attribute
    {
        public string Name { get; set; }

        public CommandAttribute(string name)
        {
            Name = name;
        }
    }

现在,在您在上面看到的方法 HandleCommand() 方法中,我存储的方法名称 属性 等于我在 MethodInfo m 中传入的字符串。现在我的问题本质上是,我如何正确调用此方法。 m.Invoke 需要一个调用它的对象,并且因为传入“this”不起作用,并且在线示例总是传入它定义的 class 的实例,我想我需要创建一个class m 的实例在中定义,只需将其传递给 Invoke() 方法。实际上,这比我想象的要难得多,我最好的猜测就是你在上面看到的,使用激活器。

ICommandSet set =(m.DeclaringType)Activator.CreateInstance(m.DeclaringType);

首先,我确定 class 中声明的 class 实现了 ICommandSet,因为这是要检查方法的类型的 creterium。所以这就是为什么我说“ICommandSet 集”。然后激活器将创建这个实例。但它不起作用。提供的唯一错误消息指出 m 是一个变量,但像类型一样使用。但是,当我将它作为参数传递给 Activator.CreateInstance() 时,编译器似乎很好地挖掘了它。我绝对不知道如何解决这个问题,因为我真的不明白问题出在哪里。有没有人可以帮助我?

另外,所有的方法都是在不同的classes甚至项目中定义的,所以我不知道这些方法是在哪个class中定义的。

您收到此消息的原因是您的语法有误。您不能以变量取消引用作为期望类型来执行强制转换。正如您已经知道的那样,您希望将“set”视为转换为“ICommandSet”的“ICommandSet”。

var set = (ICommandSet) Activator.CreateInstance(m.DeclaringType);

你也可以做到安全

var set = Activator.CreateInstance(m.DeclaringType) as ICommandSet;