创建方法的 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;
我又一次在反思中挣扎。我只是给你一段我的调试器没有咬到的代码:
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;