jeudi 19 février 2015

Using Delegate.CreateInstance with relaxed signature match

I'm trying to bind to any EventInfo at runtime without emiting any code. This means no Reflection.Emit, Expression, MakeGeneric*, etc.


The only possible solution I can think of is to have a list of methods that accept 0 to 10 object parameters and bind those method to the EventInfo. However, it seems that adding a handler to an event requires an exact signature match. By using Delegate.CreateDelegate, I could create an exact match delegate from the general methods and add that new delegate as a handler.


I have the following minimal code:



class Program
{
public static void F(object o) { }

static void Main(string[] args)
{
MethodInfo f = typeof(Program).GetMethod("F");

Delegate d1 = Delegate.CreateDelegate(typeof(Action<object>), f);
Delegate d2 = Delegate.CreateDelegate(typeof(Action<int>), f);
}

}


It works for d1 but fails with d2 with the following exception:



A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll


Additional information: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.



That is despite the documentation for Delegate.CreateDelegate explicitly stating doing that is allowed:



A parameter of a delegate is compatible with the corresponding parameter of a method if the type of the delegate parameter is more restrictive than the type of the method parameter, because this guarantees that an argument passed to the delegate can be passed safely to the method.



What am I missing?






Aucun commentaire:

Enregistrer un commentaire