2009-07-07 90 views
1

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

在我的映射类我有类似线路:

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

能正常工作,而不是在我的居住问题,在这里我设置救了我的关于表达的信息是在地图的方法:

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方法更好的方法,因为之前我使用表达式树?

+0

-1我很害怕看到你的反射帮手。 – asyncwait 2009-08-18 14:49:27

回答

1

我不明白你为什么真的需要使用表达式树。只是使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); 
} 

你有什么特别想知道的财产和使用表达式树的原因吗?

+0

如果我需要访问PropertyInfo信息(可能用于不同类型的对话/解析),或者如果我想创建基于命名风格的某种类型的默认规则,那么我开始将它保留为表达式树的唯一原因是稍后属性/类型。 – 2009-07-07 19:47:36

1

部分取决于你的场景。 “简单”的答案是只编译表达式并调用它,但如果你在一个紧密的循环中进行操作(通过委托会更快),那么这会对性能产生潜在的影响。

我不知道是否会如在此特别案件,不适用(因为agent),但避免做过多的表情编辑,你可以看看简单的场景,并直接从表达式树读取值;的PropertyInfo/FieldInfo一点点的将是比编译它快......

更多,看TryEvaluatehere,以及它是如何使用Compile作为一个备份策略(尽管你有一个已知的优势委托类型)。