我正在解析表达式树.给定ExpressionType.MemberAccess的NodeType,如何获取该Field的值?
来自C#MSDN文档:MemberAccess是表示从字段或属性读取的节点.
代码片段令人难以置信,非常有用.提前致谢!!!
我的代码看起来像这样:
public static ListFilter(Expression > filterExp) { //the expression is indeed a binary expression in this case BinaryExpression expBody = filterExp.Body as BinaryExpression; if (expBody.Left.NodeType == ExpressionType.MemberAccess) //do something with ((MemberExpressionexpBody.Left).Name //right hand side is indeed member access. in fact, the value comes from //aspdroplist.selectedvalue if (expBody.Right.NodeType == ExpressionType.MemberAccess) { //how do i get the value of aspdroplist.selected value?? note: it's non-static } //return a list }
Marc Gravell.. 40
[为清晰起见而更新]
第一; 投了Expression
一个MemberExpression
.
A MemberExpression
有两件值得关注的事:
.Member - 成员PropertyInfo
/FieldInfo
.Expression - 要评估的表达式,以获取.Member的"obj"
也就是说,如果你能评价.Expression
为"目标文件",以及.Member
是FieldInfo
,那么你可以通过获得实际值.GetValue(obj)
的FieldInfo
(并且PropertyInfo
是非常相似).
问题是评估.Expression
是非常棘手的;-p
显然,如果事实证明你是幸运的话,你会很幸运ConstantExpression
- 但在大多数情况下它并非如此; 它可能是ParameterExpression
(在这种情况下,您需要知道要评估的实际参数值),或者Expression
s的任何其他组合.
在许多情况下,一个简单的(可能是懒惰的)选项是使用.Compile()
.NET框架来完成繁重的任务; 然后,您可以将lambda计算为类型委托(传入lambda要求的任何参数).但是,这并不总是一种选择.
为了表明这是多么复杂; 考虑这个简单的例子(我在每一步都进行了硬编码,而不是测试等):
using System; using System.Linq.Expressions; using System.Reflection; class Foo { public string Bar { get; set; } } static class Program { static void Main() { Foo foo = new Foo {Bar = "abc"}; Expression> func = () => foo.Bar; MemberExpression outerMember = (MemberExpression)func.Body; PropertyInfo outerProp = (PropertyInfo) outerMember.Member; MemberExpression innerMember = (MemberExpression)outerMember.Expression; FieldInfo innerField = (FieldInfo)innerMember.Member; ConstantExpression ce = (ConstantExpression) innerMember.Expression; object innerObj = ce.Value; object outerObj = innerField.GetValue(innerObj); string value = (string) outerProp.GetValue(outerObj, null); } }
Keith Fitzge.. 24
非常感谢Marc Gravell.我非常感谢他的帮助.
事实证明,就我而言.问题可以通过以下方式解决:
object value = Expression.Lambda(expBody.Right).Compile().DynamicInvoke();
再次感谢马克!
[为清晰起见而更新]
第一; 投了Expression
一个MemberExpression
.
A MemberExpression
有两件值得关注的事:
.Member - 成员PropertyInfo
/FieldInfo
.Expression - 要评估的表达式,以获取.Member的"obj"
也就是说,如果你能评价.Expression
为"目标文件",以及.Member
是FieldInfo
,那么你可以通过获得实际值.GetValue(obj)
的FieldInfo
(并且PropertyInfo
是非常相似).
问题是评估.Expression
是非常棘手的;-p
显然,如果事实证明你是幸运的话,你会很幸运ConstantExpression
- 但在大多数情况下它并非如此; 它可能是ParameterExpression
(在这种情况下,您需要知道要评估的实际参数值),或者Expression
s的任何其他组合.
在许多情况下,一个简单的(可能是懒惰的)选项是使用.Compile()
.NET框架来完成繁重的任务; 然后,您可以将lambda计算为类型委托(传入lambda要求的任何参数).但是,这并不总是一种选择.
为了表明这是多么复杂; 考虑这个简单的例子(我在每一步都进行了硬编码,而不是测试等):
using System; using System.Linq.Expressions; using System.Reflection; class Foo { public string Bar { get; set; } } static class Program { static void Main() { Foo foo = new Foo {Bar = "abc"}; Expression> func = () => foo.Bar; MemberExpression outerMember = (MemberExpression)func.Body; PropertyInfo outerProp = (PropertyInfo) outerMember.Member; MemberExpression innerMember = (MemberExpression)outerMember.Expression; FieldInfo innerField = (FieldInfo)innerMember.Member; ConstantExpression ce = (ConstantExpression) innerMember.Expression; object innerObj = ce.Value; object outerObj = innerField.GetValue(innerObj); string value = (string) outerProp.GetValue(outerObj, null); } }
非常感谢Marc Gravell.我非常感谢他的帮助.
事实证明,就我而言.问题可以通过以下方式解决:
object value = Expression.Lambda(expBody.Right).Compile().DynamicInvoke();
再次感谢马克!