Dynamically create delegates

Recently I was facing a problem regarding delegates. I needed to dynamically create a delegate which “points to” a dynamically reflected method which is not static on a given type. The problem was, that at the time of the “inspection” of the type I had no instance of that type available. Normally delegates “pointing to” instances are said to be closed on a given  instance therefore you need to have a concrete instance of the type available which the delegate can be bound to.

An example of a closed delegate is the following:

public delegate void MyDelegate(string parameter)

But what happens if you don’t have an instance of a given type present at the time of inspection and you want to dynamically create and later assign the delegate to a type?

The class Delegate offers some static methods overload with the name Delegate.CreateDelegate. Delegate.CreateDelegate allows to dynamically create a delegate of a given type which are bound to either instance or static methods. All you need to do is retrieve a MethodInfo of the method you want to dynamically assign a delegate to and pass it together with the type of the delegate into the Delegate.CreateDelegate method like the following:

MethodInfo methodInfo = typeof(MyClass).GetMethod(“MyMethod”);
MyDelegate delegate = (MyDelegate) Delegate.CreateDelegate(typeof(MyDelegate), instanceOfMyClass, methodInfo, false);

But as previously mentioned this only works if you have an instance of the class you want to bind the delegate to. So we need an open delegate where a reference to the instance of the class can be passed into along with the parameter we want to pass to the bound method. On the first impulsive approach you might write the following delegate:

public delegate void MyDelegate(object target, string parameter);

But that does not work because the first target parameter must be strongly typed to the type of the class you want to bound the delegate to. That means in our case we would need to write:

public delegate void MyDelegate(MyClass target, string parameter);

This would work but is not really a generic approach when dealing with multiple types. The solutions is to write a generic delegate like:

public delegate void MyDelegate<ttarget>(TTarget target, string parameter);

With the generic delegate above it is possible to create a typed delegate by calling the static method MakeGenericType on System.Type passing in the open generic definition of your delegate type. After that you can simply call Delegate.CreateDelegate and pass in the newly created typed delegate.

MethodInfo methodInfo = typeof(passedInType).GetMethod(“TheMethod”);
Type delegType = typeof(MyDelegate<>).MakeGenericType(passedInType);
Delegate typedDelegate = Delegate.CreateDelegate(delegType, null, methodInfo, false);

The beauty of this approach is that with the newly created typedDelegate you can later pass your instance of passedInType and your parameter and the delegate gets dynamically assigned to the reflected method on the passedInType.

About the author

Daniel Marbach

2 comments

  • Hi Dani

    Could you provide information why you needed to create that dynamic delegate and a bit more of code how you used it.

    Cheers
    Thomas

  • Hello Thomas,
    The problem of creating dynamic delegates especially arises if you want build up a framework which inspects methods on a certain type where you have currently no concrete instance available. For example I declare a type:

    public class MyType {
    public void MyMethod() {}
    }

    Imagine you have a utility which needs to check whether a certain type passed to your utility offers a method which can be invoked from our framework when later a concrete instance is available.

    public class Utility {
    public static Delegate InspectType(Type inspectedType) {
    // apply principles described in article above
    }
    }

    later we can do the following:

    Delegate myDynamicDelegate = Utility.InspectType(typeof(MyType));
    MyType myInstance1 = new MyType();
    myDynamicDelegate.DynamicInvoke(myInstance1);

    .NET is now able to pass in the concrete instance of MyType because the dynamically created delegate myDynamicDelegate is strongly typed to MyType and the reflected method gets invoked on the instance myInstance1 of MyType.

    Is this explanation feasible for you?

    Daniel

By Daniel Marbach

Recent Posts