Attempt to create a dynamic delegate

I load a dll using loadfrom and iterate through the search methods that match the signature. When I find this, I want to appoint him as a delegate, in order to subsequently call him. This is what I do ...

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

Problem - delegate assignment does not work. I get the error binding to the target method.

I read on the Internet that the second parameter can be a problem if the method is not static. My method is NOT static.

Any ideas?

+4
source share
2 answers

Although Mika Dinescu's answer may be useful, it is only partially correct. There is an overload of Delegate.CreateDelegate , which is most likely to help you.

Firstly, Miky is right that you should pass the instance as the second parameter, but this is only if you want to create what is called a private delegate . This means that the instance is associated with the delegate along with the method. In practice, this means that when calling a delegate, he will always work with the same instance.

From your question, it seems this is not what you are trying to achieve. If you want to pass an instance when calling a delegate, you must use the CreateDelegate( Type type, MethodInfo method ) overload. This allows you to create a so-called public instance delegate .

Since you need to pass an instance when calling a method, this means that your delegate type has an extra parameter. The first parameter of your delegate type must match the type of the class that contains this method.

Example:

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

Because - like you - I found that these overloads are unclear, I created two helper functions to clearly separate the creation of a β€œnormal” delegate or an open delegate instance. This code, as well as a more detailed discussion, can be found in my blog post .

+2
source

If the method is not static, you need to pass a reference to an instance of the class whose method you are going to use using the delegate.

If you do not know which instance you will be using at the time you are trying to create the delegate, you will need to save the type and method information later, and then create the delegate after you have an instance of the class.

EDIT

To respond to your comment, the object you need to pass is an object of the type that contains the method to which you are trying to bind your delegate. Therefore, based on your sample code, this is not a Command object, but a class object from a DLL.

So let's say that you have this .NET assembly. DLL: myassembly.dll . The assembly contains the following class:

 namespace MyNamespace { public class SomeClass { public SomeClass() { } public void Method1(object Command, object ExposedVariables) { } public void Method2(object Command, object ExposedVariables) { } } 

You will need to instantiate the SomeClass class before you can create the delegates associated with Method1 or Method2 of this class. So, the code that the delegate creates should look like this:

 // 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); 
0
source

Source: https://habr.com/ru/post/1344672/


All Articles