C# 使用lambda表达式读取属性值

C# 使用lambda表达式读取属性值,c#,reflection,lambda,C#,Reflection,Lambda,我正在为我的应用程序编写一个文件通用块,并开始使用Lambda表达式来管理块生成的规则集,以避免神奇字符串、配置地狱等陷阱 在我的mapping类中,我有类似的行: Map(x => x.Name).Length(20).PadLeft(true).PaddingChar("#"); 这很好,不是我的问题所在,我设置保存表达式信息的位置是Map方法: public override IPropertyMap Map(Expression<Func<T, object>&

我正在为我的应用程序编写一个文件通用块,并开始使用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;
}

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

我不明白为什么您真的需要使用表达式树。只需使
Map
方法采用
Func
并存储以下内容:

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 IPropertyMap映射(Func fetcher)
{
var propertyMap=新的固定长度propertyMap
{
//长度=20,
//PaddingCharacter=“”,
PadLeft=false,
Delegate=fetcher//委托类型为Delegate
};
_添加(propertyMap);
返回属性映射;
}
然后:

公共重写字符串写入(T代理)
{
var initial=_属性[0];
Func fetcher=(Func)initial.Delegate;
取回器(代理);
}

是否有任何原因让您特别想了解属性并使用表达式树?

部分取决于您的场景。“简单”的答案是只编译表达式并调用它,但如果在一个紧密的循环中执行它,则可能会影响性能(传递委托会快得多)

我不确定if是否适用于这种特殊情况(因为
代理
),但为了避免进行太多的表达式编译,您可以寻找简单的场景并直接从表达式树读取值;一点
属性info
/
FieldInfo
将比编译它更快


有关更多信息,请查看
tryeevaluate
,以及它如何与
Compile
一起用作备份策略(尽管您具有已知委托类型的优势).

我开始将其保留为表达式树的唯一原因是以后如果我需要访问PropertyInfo信息,可能是为了不同类型的对话/解析,或者如果我想根据属性/类型的命名样式创建某种类型的默认规则。那么最好将其保留为表达式树,然后在需要时编译它。。。但是,如果您真的只想暂时调用PropertyInfo,那么获取PropertyInfo没有什么意义:)我基本上是这样处理表达式的(我剥离了一些空检查/验证)var body=expression.body作为MemberExpression;var propertyInfo=(propertyInfo)body.Member;这就是我在实际读取“bob”代理对象时基于.GetValue(..)的基础,这几乎是使用表达式实现这一点的主要方法,还是我使用Func的方法是错误的?如果我还不清楚,我的最终目标是获取一个列表并使用我的映射器直接从代理对象的属性访问值。如果你想将表达式用作委托,你可以对它调用Compile-这就是我的观点。要执行它,您不需要查看它的所有部分。无论如何,为了其他目的保留它们,但执行起来很简单。-1我害怕看到你的反射助手。
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);
}