给定一个类型ExpressionType.MemberAccess,我如何获取字段值? [英] Given a type ExpressionType.MemberAccess, how do i get the field value?
问题描述
我解析表达式树。鉴于ExpressionType.MemberAccess的一个nodeType,我如何获取字段的值?
从C#MSDN文档:
MemberAccess是表示从字段或属性读取节点。
一个代码片段将是令人难以置信,难以置信的帮助。在此先感谢!
我的代码看起来是这样的:
公共静态列表< T>过滤器(表达式来; Func键< T,BOOL>> filterExp)
{
//表达确实是在这种情况下,
BinaryExpression expBody = filterExp.Body作为BinaryExpression一个二进制表达式;
如果(expBody.Left.NodeType == ExpressionType.MemberAccess)
//做((MemberExpressionexpBody.Left).Name点
的东西//右手一边是确实的成员访问。事实上,价值来自//aspdroplist.selectedvalue
如果(expBody.Right.NodeType == ExpressionType.MemberAccess)
{
//我如何获得aspdroplist.selected值??音符的价值:它的非静态
}
//返回一个列表
}
[更新为清晰起见]
首先,投在表达
到 MemberExpression
。
A MemberExpression
有感兴趣的两件事情:
- 。成员 - 在
的PropertyInfo
/字段信息
的成员 - .Expression - 评估得到表达OBJ为。成员
也就是说,如果你可以评估 .Expression
来目标文件,以及。成员
是字段信息
,然后你就可以用 .GetValue(OBJ)
在字段信息
(和的PropertyInfo
很相似)。
的问题是,评估 .Expression
是非常棘手的;-p
显然,你很幸运,如果它原来是一个常量表达式
- 但在大多数情况下,它不是;它可能是一个 ParameterExpression
(在这种情况下,你需要知道你要计算的实际参数值),或的任何其他组合表达
秒。
在很多情况下,一个简单的(也许懒惰)选项是使用 .Compile()
来获得.NET框架做繁重;那么你可以评估的lambda作为一个类型代表(传入的拉姆达需要的任何参数)。这并不总是一个选项,但是
要展示如何复杂,这是;考虑这个简单的例子(其中,我的每一步硬编码,而不是测试等):
使用系统;使用System.Linq.Expressions
;
使用的System.Reflection;
类Foo
{
公共字符串酒吧{搞定;组; }
}
静态类节目
{
静态无效的主要()
{
富富=新富{吧=ABC };
表达式来; Func键<串GT;> FUNC =()=> foo.Bar;
MemberExpression outerMember =(MemberExpression)func.Body;
的PropertyInfo outerProp =(的PropertyInfo)outerMember.Member;
MemberExpression innerMember =(MemberExpression)outerMember.Expression;
字段信息innerField =(字段信息)innerMember.Member;
常量表达式CE =(常量表达式)innerMember.Expression;
对象innerObj = ce.Value;
对象outerObj = innerField.GetValue(innerObj);
字符串值=(字符串)outerProp.GetValue(outerObj,NULL);
}
}
I am parsing an Expression Tree. Given a NodeType of ExpressionType.MemberAccess, how do I get the value of that Field?
From C# MSDN docs: MemberAccess is A node that represents reading from a field or property.
A code snippet would be incredibly, incredibly helpful. Thanks in advance!!!
My code looks something like this:
public static List<T> Filter(Expression<Func<T, bool>> 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
}
[updated for clarity]
First; cast the Expression
to a MemberExpression
.
A MemberExpression
has two things of interest:
- .Member - the
PropertyInfo
/FieldInfo
to the member - .Expression - the expression to evaluate to get the "obj" for the .Member
i.e. if you can evaluate the .Expression
to "obj", and the .Member
is a FieldInfo
, then you can get the actual value via .GetValue(obj)
on the FieldInfo
(and PropertyInfo
is very similar).
The problem is that evaluating the .Expression
is very tricky ;-p
Obviously you get lucky if it turns out to be a ConstantExpression
- but in most cases it isn't; it could be a ParameterExpression
(in which case you'll need to know the actual parameter value that you want to evaluate), or any other combination of Expression
s.
In many cases, a simple (perhaps lazy) option is to use .Compile()
to get the .NET framework to do the heavy lifting; you can then evaluate the lambda as a typed delegate (passing in any parameters that the lambda requires). This isn't always an option, however.
To show how complex this is; consider this trivial example (where I've hard-coded at every step, rather than testing etc):
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<string>> 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);
}
}
这篇关于给定一个类型ExpressionType.MemberAccess,我如何获取字段值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!