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.