【发布时间】:2010-08-31 18:48:10
【问题描述】:
我正在尝试编写一个帮助类来表示对象上的字段。辅助类需要能够获取给定实例上字段的值,并返回有关它可以通过反射获得的基础属性的元数据。
我希望通过一个实用方法来创建帮助程序类,该方法被调用如下:
public IEnumerable<IFieldInfo<SomeType>> Fields {
get {
yield return FieldHelper.GetFieldInfo<SomeType>(t => t.SomeField);
yield return FieldHelper.GetFieldInfo<SomeType>(t => t.SomeOtherField);
}
}
说IFieldInfo接口看起来有点像这样:
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 辅助函数来获取单个参数并将其解释为表达式树和委托,而无需在运行时将表达式树编译为委托?
【问题讨论】:
-
Compile() 是解决方案。您可以缓存结果,并且总调用次数是静态绑定的。如果以这种方式实施,我怀疑性能是否会成为问题。
-
总调用次数不是完全静态绑定的;字段可以被多次调用。除非你说 Expression 本身是一个有效的 Dictionary 键?
标签: c# linq c#-4.0 expression-trees