首页 > 解决方案 > 通过反射访问泛型类中泛型实例的私有成员

问题描述

我查看了可能重复的问题,其中任何一个都没有回答这个问题,包括通过通用类型参数访问属性

TLDR;即使在设置了 NonPublic BindingFlag 的情况下,T 未声明为 publictypeof(T).GetProperty(propertyName, BindingFlags.NonPublic)时,它也不能在泛型类中工作。propertyName有解决方法吗?

我已经实现了一个扩展方法,它从提供的字符串中生成一个 IOrderedQueryable,该字符串包含在实体框架环境中排序所需的列。目标是允许以字符串形式编写 Order By 子句,例如“+Age,+State,-Name”,并生成必要的表达式以按年龄、状态和名称(降序)对实体框架结果进行排序,而不是使用来写:

.OrderBy(m=>m.Age).ThenBy(m=>m.State).ThenByDescending(m=>m.Name).

当我尝试访问标记为内部的类属性时,问题就出现了。我似乎找不到任何方法来强制反射以找到该内部属性。

在这种特殊情况下,我在数据库中有一个存储 UTC 的日期时间字段,但我希望最终用户在本地时间使用它,因此值 startTime,一个内部范围的属性绑定到数据库,并且 StartTime 用作公共访问器并提供对 startTime 值的访问,执行必要的本地时间映射。我有一个定义如下的类:

public class TimeInterval { 
   //other properties...
   internal startTime { get; set; } // bound to database, stores time in UTC
   public StartTime { 
      get { /*convert startTime to local time*/; } 
      set { /*convert value back to UTC and store in startTime*/;  }
   }
}

使用 EF,我可以编写.OrderBy( m=>m.startTime )它并按预期工作;当然我不能使用.OrderBy( m=>m.StartTime ),因为它是派生的。

在我的扩展函数中,其签名是

static public IOrderedQueryable<T> ParseOrderBy<T>( 
   this IQueryable<T> query, 
   string orderBy 
   )

我会调用它:

var query = query.ParseOrderBy<TimeInterval>( "startTime" );

我调用获取属性引用以构建lamba 表达式返回null。

var property = typeof( T ).GetProperty( "startTime", BindingFlags.NonPublic );

property对于未明确公开的任何内容返回 null。

扩展方法与我期望它运行的类在同一个命名空间和程序集中。

标签: c#genericsreflectionentity-framework-6extension-methods

解决方案


推荐阅读