给定一个类型ExpressionType.MemberAccess,我如何获取字段值? [英] Given a type ExpressionType.MemberAccess, how do i get the field value?

查看:1624
本文介绍了给定一个类型ExpressionType.MemberAccess,我如何获取字段值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我解析表达式树。鉴于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 Expressions.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆