给定一个类型ExpressionType.MemberAccess,如何获取字段值

本文关键字:何获取 获取 字段 ExpressionType 一个 类型 MemberAccess | 更新日期: 2023-09-27 17:47:23

我正在解析表达式树。给定 ExpressionType.MemberAccess 的 NodeType,如何获取该字段的值?

来自 C# MSDN 文档:MemberAccess 是一个节点,表示从字段或属性读取。

代码片段将令人难以置信,非常有帮助。提前谢谢!!

我的代码看起来像这样:

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
}

给定一个类型ExpressionType.MemberAccess,如何获取字段值

[为清楚起见进行了更新]

首先; 将Expression投向MemberExpression

MemberExpression有两件有趣的事情:

  • .会员 - 会员的PropertyInfo/FieldInfo
  • .表达式 - 要计算以获取 的"obj" 的表达式。成员

即,如果您可以将.Expression评估为 "obj",并且.Member是一个FieldInfo,那么您可以通过FieldInfo上的.GetValue(obj)获得实际值(并且PropertyInfo非常相似)。

问题是评估.Expression非常棘手;-p

显然,如果它被证明是一个ConstantExpression,你会很幸运 - 但在大多数情况下它不是;它可能是一个ParameterExpression(在这种情况下,你需要知道你想要评估的实际参数值),或任何其他Expression的组合。

在许多情况下,一个简单的(可能是懒惰的)选项是使用 .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<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);    
    }
}
非常感谢

上面的Marc Gravell。我真的很感谢他的帮助。

事实证明,就我而言。 这个问题可以通过以下方式解决:

object value = Expression.Lambda(expBody.Right).Compile().DynamicInvoke();

再次感谢马克!