-1

I'm constructing generic, reusable reflection C# code, in .NET Core 2, with the aim of storing delegates for reuse, to avoid most reflection overhead. The first use case of this code is to get property values. My basic question is how to construct a delegate to call public properties of an inherited type.

I have a class which essentially serves as a reflection wrapper/adapter for a target class, using a generic type parameter T as a crucial parameter to Delegate.CreateDelegate as follows:

        someDelegateStoredForReuse = (Func<T, object>)Delegate.CreateDelegate(typeof(Func<T, object>), null, PropertyInfo.GetGetMethod());

The way the code is structured the wrapper/adapter actually stores and reuses wrappers around each property getter, where the above line of code appears. When the wrapper class is instantiated, it loops over the PropertyInfo objects returned by typeof(T).GetProperties() , and for each one constructs a property wrapper.

That's all working for public properties on the class itself, but not for inherited ones. No combination of binding flags passed to GetProperties(), including BindingFlags.FlattenHierarchy in conjunction with Public | NonPublic, returns inherited properties which will work for this purpose.

To get the inherited properties, I've switched to getting them from the type's base type and walking the ancestor line. However, I can't get Delegate.CreateDelegate to work with this approach because I can't get the generic type argument of the ancestor from its System.Type . Calling Delegate.CreateDelegate to create a Func with the inherited property's .GetGetMethod() doesn't work because T is not the parent/ancestor type (it throws an exception when the delegate is called).

My problem would be solved by one of the following solutions, neither of which I have been able to find using .NET Core 2, at least:

  1. Call Delegate.CreateDelegate to create a working delegate to call the MethodInfo of a reflected property getter, using a type not passed as a generic parameter, i.e. using a System.Type

  2. Get PropertyInfo objects for inherited properties in the initial .GetProperties() call, iff the returned PropertyInfos' .GetGetMethod() would return a MethodInfo allowing creation of a working delegate using the passed generic type T of the inheriting type

My apologies for the wordiness, but I wanted to be precise. Thank you for any insight.

  • Could you please illustrate your question with corresponding code snippets? Sometimes it's just way easier to read code than reading a long description. Especially for us, software people. – dymanoid Oct 06 '19 at 13:19
  • I already did. See the call to Delegate.CreateDelegate . The problem is how to call Delegate.CreateDelegate with an inherited type. – wildzooyonder Oct 06 '19 at 13:24
  • Something like that? https://dotnetfiddle.net/3YL66L – Kevin Gosse Oct 06 '19 at 13:30
  • It sounds like you complain GetProperty(string name) is not returning the property, if it's inherited. You mix up terms like "inherited method", and properties. You mean inherited properties ? We have no clue what T is, the delegate signature has to match 100%, it does not support inheritance. – Holger Oct 06 '19 at 15:27
  • @Holger re: "We have no clue what T is", this is generally the case with generic types that have no constraints. ;) – wildzooyonder Oct 06 '19 at 15:40
  • @KevinGosse Perfect! Thank you. If you care about points, please add it as an answer and I'll accept. ETA: Unfortunately it looks like DynamicInvoke is poor on performance: https://stackoverflow.com/questions/12858340/difference-between-invoke-and-dynamicinvoke – wildzooyonder Oct 06 '19 at 15:50

1 Answers1

1

You can use Expression.GetFuncType to generate a Func<> with the generic parameters you want.

var delegateType = Expression.GetFuncType(property.DeclaringType, property.PropertyType);
var getter = property.GetMethod.CreateDelegate(delegateType);
Kevin Gosse
  • 38,392
  • 3
  • 78
  • 94