【问题标题】:Constructing a C# delegate to call inherited property getter构造一个 C# 委托以调用继承的属性 getter
【发布时间】:2020-02-04 00:53:52
【问题描述】:

我在 .NET Core 2 中构建通用、可重用的反射 C# 代码,目的是存储委托以供重用,以避免大部分反射开销。此代码的第一个用例是获取属性值。我的基本问题是如何构造一个委托来调用继承类型的公共属性

我有一个类,它基本上用作目标类的反射包装器/适配器,使用泛型类型参数 T 作为 Delegate.CreateDelegate 的关键参数,如下所示:

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

代码的结构方式包装器/适配器实际上存储和重用每个属性获取器周围的包装器,上面的代码行出现在其中。当包装器类被实例化时,它会遍历 typeof(T).GetProperties() 返回的 PropertyInfo 对象,并为每个对象构造一个属性包装器。

这一切都适用于类本身的公共属性,但不适用于继承的公共属性。没有传递给 GetProperties() 的绑定标志组合,包括 BindingFlags.FlattenHierarchy 与 Public | NonPublic,返回用于此目的的继承属性。

为了获取继承的属性,我已经切换到从类型的基本类型中获取它们并走祖先线。但是,我无法让 Delegate.CreateDelegate 使用这种方法,因为我无法从其 System.Type 获取祖先的泛型类型参数。 调用 Delegate.CreateDelegate 以使用继承属性的 .GetGetMethod() 创建 Func 不起作用,因为 T 不是父/祖先类型(调用委托时会引发异常)。

我的问题将通过以下解决方案之一解决,至少我无法使用 .NET Core 2 找到这两种解决方案:

  1. 调用 Delegate.CreateDelegate 以创建一个工作委托以调用反射属性 getter 的 MethodInfo,使用未作为泛型参数传递的类型,即使用 System.Type

  2. 在初始 .GetProperties() 调用中获取继承属性的 PropertyInfo 对象,如果返回的 PropertyInfos' .GetGetMethod() 将返回 MethodInfo 允许使用传递的继承类型的泛型类型 T 创建工作委托

我为冗长而道歉,但我想准确地说。感谢您的任何见解。

【问题讨论】:

  • 你能用对应的代码sn-ps来说明你的问题吗?有时阅读代码比阅读长描述要容易得多。尤其是对于我们这些软件人。
  • 我已经做到了。请参阅对 Delegate.CreateDelegate 的调用。问题是如何使用继承的类型调用 Delegate.CreateDelegate。
  • 类似的东西? dotnetfiddle.net/3YL66L
  • 听起来你抱怨 GetProperty(string name) 没有返回属性,如果它是继承的。您将“继承方法”和属性等术语混为一谈。你的意思是继承的属性?我们不知道 T 是什么,委托签名必须 100% 匹配,它不支持继承。
  • @Holger re:“我们不知道 T 是什么”,这通常是没有约束的泛型类型的情况。 ;)

标签: c# generics reflection .net-core properties


【解决方案1】:

您可以使用Expression.GetFuncType 生成带有所需通用参数的Func&lt;&gt;

var delegateType = Expression.GetFuncType(property.DeclaringType, property.PropertyType);
var getter = property.GetMethod.CreateDelegate(delegateType);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2015-07-28
    • 1970-01-01
    相关资源
    最近更新 更多