我正在尝试编写一个表示对象字段的辅助类。帮助程序类需要能够获取给定实例上字段的值,并返回有关它可以通过反射获取的基础属性的元数据。
我希望通过实用方法创建辅助类,该实用方法的调用方式如下:
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/