问题描述
|
我正在使用loadfrom加载dll,并反复遍历方法以查找与签名匹配的方法。当我找到它时,我想将其分配为代理,以便稍后调用。这就是我在做的...
foreach (MethodInfo method in methodInfos)
{
if (method.GetParameters().Length == 2)
{
ParameterInfo[] parameters = method.GetParameters();
if (parameters[0].ParameterType.Name == \"Command\"
&& parameters[1].ParameterType.Name == \"ExposedVariables\")
{
aoc.methodinfo = method;
Command.delCmdMethod del = (Command.delCmdMethod)
Delegate.CreateDelegate(typeof(Command.delCmdMethod),null,method);
}
}
}
问题是-委托分配不起作用。我收到与目标方法绑定的错误。
我在网上读到,如果方法不是静态的,第二个参数可能是问题。我的方法不是静态的。
有任何想法吗?
解决方法
尽管Miky Dinescu的回答可能会有所帮助,但仅部分正确。 ѭ1确实存在过载,这很可能会帮助您。
首先,Miky是正确的,您必须将实例作为第二个参数传递,但是只有在您要创建所谓的封闭委托时才是这种情况。这意味着实例与方法一起绑定到委托。实际上,这意味着在调用委托时,它将始终在同一实例上运行。
从您的问题来看,这似乎不是您要实现的目标。如果要在调用委托时能够传递实例,则必须使用
CreateDelegate( Type type,MethodInfo method )
重载。这使您可以创建所谓的开放实例委托。
由于调用该方法时必须传递实例,这意味着委托类型中需要一个额外的参数。您的委托类型的第一个参数将需要对应于包含该方法的类的类型。
例:
MethodInfo toUpperMethod
= typeof( string ).GetMethod( \"ToUpper\",new Type[] { } );
Func<string,string> toUpper
= (Func<string,string>)Delegate.CreateDelegate(
typeof( Func<string,string> ),toUpperMethod );
string upper = toUpper( \"test\" ); // Will result in \"TEST\".
因为-和您一样-我发现这些重载尚不清楚,所以我创建了两个帮助器函数来清楚地分开创建\'normal \'委托或开放实例委托。可以在我的博客文章中找到该代码以及更详尽的讨论。
, 如果方法不是静态的,则需要传递对要使用委托进行调用的类的实例的引用。
如果您在尝试创建委托时不知道将使用哪个实例,则需要存储类型和方法信息以供以后使用,然后在拥有该类的实例之后创建委托。
编辑
为了回答您的评论,您需要传递的对象是包含尝试将委托绑定到的方法的类型的对象。因此,根据您的代码示例,它不是Command对象,而是DLL中类的对象。
因此,假设您拥有此.NET程序集DLL:myassembly.dll
。该程序集包含以下类:
namespace MyNamespace
{
public class SomeClass
{
public SomeClass()
{
}
public void Method1(object Command,object ExposedVariables)
{
}
public void Method2(object Command,object ExposedVariables)
{
}
}
您需要先创建SomeClass类的实例,然后才能创建绑定到该类的Method1或Method2的委托。因此,创建委托的代码应如下所示:
// assuming that method info is a MethodInfo contains information about the method
// that you want to create the delegate for,create an instance of the class which
// contains the method..
object classInstance = Activator.CreateInstance(methodInfo.DeclaringType);
// and then create the delegate passing in the class instance
Delegate.CreateDelegate(typeof(Command.delCmdMethod),classInstance,methodInfo);