尝试创建一个动态委托

4

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

问题在于委托分配无法正常工作。我收到一个绑定到目标方法的错误。

我在网上读到,如果该方法不是静态的,则第二个参数可能是问题。我的方法不是静态的。

有什么想法吗?

2个回答

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".

由于我和你一样,觉得这些过载函数不太清晰,所以我创建了两个辅助函数来明确区分创建“普通”委托或开放实例委托。这段代码以及更详细的讨论可以在我的博客文章中找到


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)
         {
         }
} 

你需要先创建一个 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);

我已经阅读了这篇文章,但不确定我需要在这里使用哪个对象。是Command,因为那里有委托,还是方法所在的对象? - Jeff
首先,感谢迄今为止的帮助...我按照您所说的做了 - 保存了程序集和方法信息,然后尝试使用上面的完全相同的代码创建委托,但是我仍然收到相同的错误。 - Jeff
你是否尝试使用其他程序集?我建议你创建一个新项目,创建一个简单的程序集,并将其设置为库文件,只包含一个类,例如我在示例中提到的那个,其中有两个不做任何特殊操作的简单方法。然后再用你的代码执行这个程序集。如果仍然无法正常工作,请尝试发布更多源代码,我们会一起解决问题。 - Mike Dinescu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接