使用 lambda 表达式读取属性值
我正在为我的应用程序编写一个文件通用块,并开始使用 Lambda 表达式来管理块生成的规则集,以避免魔术字符串、配置地狱等的陷阱。
在我的映射类中,我有类似以下内容的行:
Map(x => x.Name).Length(20).PadLeft(true).PaddingChar("#");
This Works Fine这不是我的问题所在,我在 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
我的问题是从属性中读取真实对象的数据的最佳方法是什么,目前我想出了与此类似的方法:
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 方法更好的方法,因为早些时候我使用的是表达式树?
I'm writing a file generic block for my application and started with using Lambda expressions for managing my rule sets for block generation to avoid the pitfalls of magic strings, configuration hell etc.
Inside my mapping class I have lines similar to:
Map(x => x.Name).Length(20).PadLeft(true).PaddingChar("#");
This works fine and isn't where my question dwells, where I setup saving my information about the expression is in the Map method:
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
is just a List<IPropertyMap>
that stores my info where my question from what is the best way to have a real object's data be read from the properties currently I came up with something similar to this:
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;
}
Is there a better way than using the GetValue method since earlier on I'm using an expression tree?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我根本不明白为什么你真的需要使用表达式树。 只需让
Map
方法采用Func
并将其存储:那么:
您是否特别想了解该属性并使用表达式树?
I don't see why you really need to use expression trees at all. Just make the
Map
method take aFunc<T, object>
and store that:Then:
Is there any reason you particularly wanted to know the property and use an expression tree?
在某种程度上,这取决于您的场景。 “简单”的答案是只编译表达式并调用它,但如果您在紧密循环中执行此操作,则会产生潜在的性能影响(传递委托会快得多)。
我不确定 if 是否适用于这种特定情况(因为
代理
),但为了避免进行过多的表达式编译,您可以寻找简单的场景和直接从表达式树中读取值; 一点PropertyInfo
/FieldInfo
会比编译它更快...有关更多信息,请查看
TryEvaluate
此处,以及如何将其与Compile
一起用作备份策略(尽管您具有已知委托类型的优势)。In part, it depends on what your scenario is. The "simple" answer is to just compile the expression and invoke it, but that has a potential performance impact if you are doing it in a tight loop (passing a delegate would be a lot quicker).
I'm not sure whether if would apply in this particular case (because of the
agent
), but to avoid doing too much expression compilation, you can look for simple scenarios and read the value directly from the expression tree; a little bit ofPropertyInfo
/FieldInfo
is going to be quicker than compiling it...For more, look at
TryEvaluate
here, and how it is used withCompile
as a backup strategy (although you have the advantage of a known delegate type).