代码之家  ›  专栏  ›  技术社区  ›  Stuart

我可以接受同一参数中的委托类型t和表达式<t>?

  •  3
  • Stuart  · 技术社区  · 15 年前

    我正在尝试编写一个表示对象上字段的助手类。helper类需要既能获取给定实例上字段的值,又能返回通过反射可以获得的底层属性的元数据。

    我希望助手类是由一个实用方法创建的,该方法被调用如下:

    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 简单明了;复制字段列表或复制参数只是 询问 对于不同步的错误。

    那么,我该怎么写呢 获取信息 ?如果我这样做:

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

    然后我可以实施 获取值() 通过打电话 getter(obj) 但我无法访问这个名字。

    另一方面,如果我:

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

    然后我可以提取表达式表示的属性访问的名称,但这是实现 获取值() 是呼叫 Compile() 在表达式上,我认为对于编译器本身可以为我编译的东西来说,这是一个荒谬的开销,特别是自 获取值() 在这些对象上使用的频率比 属性名 是。

    有什么方法可以写我的 获取信息 helper函数接受单个参数并将其解释为表达式树和委托,而不需要在运行时将表达式树编译为委托的开销?

    1 回复  |  直到 15 年前
        1
  •  1
  •   James Curran    15 年前

    我看不出有什么可能。委托和表达式是两种不同的对象类型,恰好看起来相似。它类似于写作:

      MyFunc("10m");
    

    将参数同时作为字符串和小数处理,而不进行任何转换。

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