c# - 我可以在同一参数中同时接受委托(delegate)类型 T 和 Expression<T> 吗?

标签 c# linq c#-4.0 expression-trees

我正在尝试编写一个表示对象字段的辅助类。帮助程序类需要能够获取给定实例上字段的值,并返回有关它可以通过反射获取的基础属性的元数据。

我希望通过实用方法创建辅助类,该实用方法的调用方式如下:

public IEnumerable<IFieldInfo<SomeType>> Fields {
  get {
    yield return FieldHelper.GetFieldInfo<SomeType>(t => t.SomeField);
    yield return FieldHelper.GetFieldInfo<SomeType>(t => t.SomeOtherField);
  }
}

假设 IFieldInfo 接口(interface)看起来有点像这样:

interface IFieldInfo<in T> {
  public string PropertyName {get;}
  public object GetValue(T obj);
}

在我的应用程序上下文中,Fields 属性将被频繁访问; GetValue() 方法将被相当频繁地调用,但是 PropertyName(以及为清楚起见我省略的其他元数据/反射字段)将被访问的频率较低。有很多地方需要实现 Fields 属性,有时还有很多字段,因此调用 GetFieldInfo 的代码对于代码清晰度和维护很重要简单明了;复制字段列表或复制参数只是询问不同步的错误。

那么,我该如何编写 GetFieldInfo?如果我这样做:

public static IFieldInfo<T> GetFieldInfo<T>(Func<T, object> getter);

然后我可以通过调用 getter(obj) 简单地实现 GetValue() 但我无法访问名称。

另一方面,如果我这样做:

public static IFieldInfo<T> GetFieldInfo<T>(Expression<Func<T, object>> getter)

然后我可以提取由表达式表示的属性访问的名称,但是实现 GetValue() 的唯一方法是调用 Compile()表达式,我认为对于编译器本身可以为我编译的东西来说,这是一个荒谬的开销,特别是因为 GetValue() 在这些对象上的使用比 PropertyName 是。

有什么方法可以编写我的 GetFieldInfo 辅助函数来获取单个参数并将其解释为表达式树和委托(delegate),而无需在运行时将表达式树编译为委托(delegate)的开销?

最佳答案

我看不出任何可行的方法。委托(delegate)和表达式是两种不同的对象类型,只是它们看起来很像。这类似于写作:

  MyFunc("10m");

并且在不进行任何转换的情况下将参数视为字符串和小数。

最好的办法是调用 Compile() 并缓存结果。我假设您已经计划缓存通过表达式搜索属性名称的结果。

关于c# - 我可以在同一参数中同时接受委托(delegate)类型 T 和 Expression<T> 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3612174/

相关文章:

c# - Global.asax 魔法函数

c# - 根据格式从字符串中获取值

c# - 在实体版本 6 的 WCF 中使用 'include' 语法时,复杂对象不会返回

c# - 如何将数据表设置为 WPF 数据网格 C#?

c# - 将字符串拆分为字典作为键,列表

c# - 在定义后立即执行 lambda 表达式?

c# - 使用 linq 规范化对象

c# - Linq group by property 表现

c# - 使用 LINQ 获取多个节点值

c# - 无法重载具有类型约束的泛型方法