5

In .NET 2.0 (with C# 3.0), how can I create a delegate for a property accessor obtained via reflection when I don't know its type at compile time?

E.g. if I have property of type int, I can do this:

Func<int> getter = (Func<int>)Delegate.CreateDelegate(
    typeof(Func<int>),
    this, property.GetGetMethod(true));
Action<int> setter = (Action<int>)Delegate.CreateDelegate(
    typeof(Action<int>),
    this, property.GetSetMethod(true));

but if I do not know what type the property is at compile time, I don't know how to do it.

Ergwun
  • 12,579
  • 7
  • 56
  • 83
  • 1
    Not sure but this the following question looks related: http://stackoverflow.com/questions/773099/generating-delegate-types-dynamically-in-c – Till Aug 30 '11 at 07:27
  • `Func` is .NET 3.5.... is this a custom `Func`? – Marc Gravell Aug 30 '11 at 07:28
  • @Marc Gravell - Whoops was actually playing around in a scratch project targeting the wrong platform, but it does work with a custom Func in .NET 2.0. – Ergwun Sep 02 '11 at 01:05

1 Answers1

3

What you need is:

Delegate getter = Delegate.CreateDelegate(
    typeof(Func<>).MakeGenericType(property.PropertyType), this,
    property.GetGetMethod(true));
Delegate setter = Delegate.CreateDelegate(
    typeof(Action<>).MakeGenericType(property.PropertyType), this,
    property.GetSetMethod(true));

however, if you are doing this for performance, you are still going to come up short, since you would need to use DynamicInvoke(), which is slooow. You might want to look at meta-programming to write a wrapper that takes/returns object. Or look at HyperDescriptor which does this for you.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • What about http://stackoverflow.com/questions/2490828/createdelegate-with-unknown-types ? – Till Aug 30 '11 at 07:32
  • @Till if you mean the accepted answer... if you don't know the type in advance, you are going to have to use `MakeGenericMethod()`; it then uses reflection to create a delegate to immediately use once and discard. Frankly, in that example, raw reflection (`GetValue()`/`SetValue()`) would have been better. – Marc Gravell Aug 30 '11 at 07:37
  • @Marc Gravel - Yes, was trying to do it for performance. I will check out HyperDescriptor when I have more time - looks amazing. – Ergwun Aug 30 '11 at 13:25
  • @Ergwun I can talk you through about 3 other ways of achieving similar ends if you need something lighter-weight; let me know. ILGenerator leaps to mind – Marc Gravell Aug 30 '11 at 20:16
  • @Ergwun will add something later – Marc Gravell Aug 31 '11 at 15:58