views:

324

answers:

1

Right now, I have to do this

private delegate void set(int obj); //declare the prototype

...
Delegate delegate1 = Delegate.CreateDelegate(typeof(set), new testObject(), props[0].GetSetMethod());

((set)delegate1)(1);

Is there a way to CreateDelegate without that prototype and call it with any parameter? GetSetMethod() returns a very specific MethodInfo that takes a specific type as an argument.

Thanks

+1  A: 

In .NET 3.5 you can use Expression.GetActionType:

    Type setterType = Expression.GetActionType(props[0].PropertyType);
    Delegate delegate1 = Delegate.CreateDelegate(setterType,
        new testObject(), props[0].GetSetMethod()
    );

Or if you want an open delegate (i.e. to any testObject instance, not bound to the new one):

    Type setterType = Expression.GetActionType(
        props[0].DeclaringType, props[0].PropertyType);
    Delegate delegate1 = Delegate.CreateDelegate(setterType,
        null, props[0].GetSetMethod()
    );

However; note that you'd have to use these delegates via DynamicInvoke, which is much slower than using a fully typed delegate via Invoke.

Another option (for this scenario) is to bind to a delegate that takes object, and use casting inside the delegate - via perhaps some fancy generics, a compiled Expression, or custom IL.

Marc Gravell
He can also just pass `typeof(Action<int>)` to `CreateDelegate`. :)
280Z28
The above is because I don't want to write a delegate prototype for each possible type (int, double, ... user defined types).
jameszhao00
Ah yea I benchmarked DynamicInvoke. It takes 5000+ ms when the direct delegate takes ~15ms. I was hoping for a direct-call delegate that will auto-cast to the required type of the Set method.
jameszhao00
@280Z28 - I was intentionally leaving it for the most general case where all we have is a PropertyInfo.
Marc Gravell