尝试创建动态委托

问题描述

| 我正在使用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);