c# - 给定类型 ExpressionType.MemberAccess,如何获取字段值?

标签 c# reflection expression-trees

我正在解析表达式树。给定 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
}

最佳答案

[为清楚起见更新]

首先;类型转换 ExpressionMemberExpression .

A MemberExpression有两件事很有趣:

  • .Member - PropertyInfo/FieldInfo给成员(member)
  • .Expression - 为获得 .Member 的“obj”而计算的表达式

即如果你能评估.Expression到“obj”,以及 .MemberFieldInfo , 然后你可以通过 .GetValue(obj) 得到实际值在 FieldInfo 上(和 PropertyInfo 非常相似)。

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

显然,如果结果是 ConstantExpression,你就走运了。 - 但在大多数情况下不是;它可能是 ParameterExpression (在这种情况下,您需要知道要评估的实际参数值),或 Expression 的任何其他组合

在许多情况下,一个简单(也许是懒惰)的选择是使用 .Compile()让 .NET 框架来完成繁重的工作;然后,您可以将 lambda 评估为类型化委托(delegate)(传入 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);    
    }

}

关于c# - 给定类型 ExpressionType.MemberAccess,如何获取字段值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/238765/

相关文章:

c# - RichTextBox 控件仅使用第一种格式

用于遗传编程的 C# 动态树

java - 反射api中object.getClass()方法的使用

c# - 在 silverlight 中使用反射调用 routedevents 上注册的事件处理程序

c# - 将 MemberInitExpression 分配给属性的 ExpressionTree 方法

c# - 动态 Linq where 子句抛出 OutOfMemoryException

c# - 如何获取通过 Polly 重试策略执行的委托(delegate)中的重试计数?

c# - XMLSerializer 没有正确地为 List 类型的属性反序列化 XML

c# - 如何使来自 Resources.resw 的字符串显示在设计器中?

java - 我的类是其他泛型类的子类吗?