代码之家  ›  专栏  ›  技术社区  ›  Chris Marisic

用lambda表达式读取属性值

  •  1
  • Chris Marisic  · 技术社区  · 15 年前

    我正在为我的应用程序编写一个通用的文件块,并开始使用lambda表达式来管理生成块的规则集,以避免魔法字符串、配置地狱等的陷阱。

    在我的mapping类中,我有类似以下的行:

    Map(x => x.Name).Length(20).PadLeft(true).PaddingChar("#");
    

    这很好,不是我的问题所在,我设置保存关于表达式的信息的位置在map方法中:

    public override IPropertyMap Map(Expression<Func<T, object>> expression)
    {
        var propertyMap = new FixedLengthPropertyMap
              {
                  //Length = 20,
                  //PaddingCharacter = " ",
                  PadLeft = false,
                  PropertyInfo = ReflectionHelper.GetProperty(expression)
              };
    
        _properties.Add(propertyMap);
    
        return propertyMap;
    }
    

    _properties 只是一个 List<IPropertyMap> 它将我的信息存储在我的问题所在,从什么样的最佳方式可以从当前的属性中读取真实对象的数据,我想出了类似的方法:

    var map = new AgentMap();
    var agent = new Agent {Name = "Bob"};
    
    string output = map.Write(agent);
    
    public override string Write<T>(T agent)
    {
        var initial = _properties[0];
        return initial.PropertyInfo.GetValue(agent, null) as string;
    }
    

    有没有比使用getValue方法更好的方法,因为之前我使用的是表达式树?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Jon Skeet    15 年前

    我不明白为什么你真的需要使用表达式树。只是让 Map 方法采取 Func<T, object> 并存储:

    public override IPropertyMap Map(Func<T, string> fetcher)
    {
        var propertyMap = new FixedLengthPropertyMap
              {
                  //Length = 20,
                  //PaddingCharacter = " ",
                  PadLeft = false,
                  Delegate = fetcher // Delegate is of type Delegate
              };
    
        _properties.Add(propertyMap);
    
        return propertyMap;
    }
    

    然后:

    public override string Write<T>(T agent)
    {
        var initial = _properties[0];
        Func<T, string> fetcher = (Func<T, string>) initial.Delegate;
        return fetcher(agent);
    }
    

    您是否有任何理由特别想了解该属性并使用表达式树?

        2
  •  1
  •   Marc Gravell    15 年前

    在某种程度上,这取决于您的场景是什么。“简单”的答案是只编译表达式并调用它,但是如果您在一个紧密的循环中执行它,这会对性能产生潜在的影响(传递委托会更快)。

    我不确定是否可以申请这个 特定的 案例(因为 agent ,但是为了避免进行过多的表达式编译,可以查找简单的场景,并直接从表达式树中读取值;有一点 PropertyInfo / FieldInfo 比编译它快…

    更多信息,请看 TryEvaluate here 以及如何与 Compile 作为备份策略(尽管您具有已知委托类型的优势)。