我正在使用loadfrom加载一个dll并通过方法迭代来查找与签名匹配的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);
}
}
}
问题是 - 委托分配不起作用。我得到一个绑定到目标方法的错误。
我在网上看到如果方法不是静态的话,第二个参数可能是问题。我的方法不是静态的。
有什么想法吗?
答案 0 :(得分:2)
尽管Miky Dinescu的回答可能有所帮助,但它只是部分正确。 Delegate.CreateDelegate
确实存在过载,这很可能对您有所帮助。
首先,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".
因为 - 就像你一样 - 我发现这些重载不清楚,我创建了两个辅助函数来清楚地分开创建一个'普通'委托或一个开放实例委托。此代码以及更全面的讨论can be found in my blog post。
答案 1 :(得分:0)
如果方法不是静态的,那么你需要传入一个对你要使用委托调用的方法的类实例的引用。
如果您在尝试创建委托时不知道将使用哪个实例,则需要存储类型和方法信息以供日后使用,然后在获得实例后创建委托。类。
修改的
要回答您的注释,您需要传递的对象是包含您尝试将代理绑定到的方法的类型的对象。因此,基于您的代码示例,它不是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)
{
}
}
在创建绑定到该类的Method1或Method2的委托之前,您需要创建SomeClass类的实例。因此,创建委托的代码应如下所示:
// 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);