我如何从表达式树中访问局部变量的值

通过检查表达式树,我可以得到一个常量,实例字段和属性的值,但不是在方法中定义的局部变量。

执行以下操作将输出1,2,3(来自常量,实例字段和属性),然后是一个异常,因为我不知道如何获取FieldInfo声明的实例,以便为本地调用GetValue()变量。

using System;
using System.Linq.Expressions;
using System.Reflection;

namespace Example
{
    class Program
    {
        private int _intField = 2;

        static void Main()
        {
            new Program().Run();
            Console.ReadLine();
        }

        private void Run()
        {
            IntProp = 3;
            var intVariable = 4;
            Test(() => 1);
            Test(() => _intField);
            Test(() => IntProp);
            Test(() => intVariable);
        }

        public int IntProp { get; set; }

        void Test<T>(Expression<Func<T>> func)
        {
            var body = func.Body;

            if (body.NodeType == ExpressionType.Constant)
            {
                Console.WriteLine(((ConstantExpression)body).Value);
            }
            else
            {
                var memberExpression = body as MemberExpression;

                var @object = memberExpression.Member.DeclaringType == GetType()
                    ? this
                    : null; //Can I do anything here? Instance of the method the variable is defined in?

                if (memberExpression.Member.MemberType == MemberTypes.Field)
                {
                    Console.WriteLine(((FieldInfo)memberExpression.Member).GetValue(@object));
                }
                else if (memberExpression.Member.MemberType == MemberTypes.Property)
                {
                    Console.WriteLine(((PropertyInfo)memberExpression.Member).GetValue(@object));
                }
            }
        }
    }
}

由lambda捕获并包含在表达式树中的局部变量当时在某些编译器生成的类中确实是一个字段。 这适用于我的.NET版本:

void Test<T>(Expression<Func<T>> func)
{
  var body = func.Body;

  if (body.NodeType == ExpressionType.Constant)
  {
    Console.WriteLine(((ConstantExpression)body).Value);
  }
  else
  {
    var memberExpression = (MemberExpression)body;

    var @object = 
      ((ConstantExpression)(memberExpression.Expression)).Value; //HERE!

    if (memberExpression.Member.MemberType == MemberTypes.Field)
    {
      Console.WriteLine(((FieldInfo)memberExpression.Member).GetValue(@object));
    }
    else if (memberExpression.Member.MemberType == MemberTypes.Property)
    {
      Console.WriteLine(((PropertyInfo)memberExpression.Member).GetValue(@object));
    }
  }
}

当然,你也可以“作弊”:

void Test<T>(Expression<Func<T>> func)
{
  Console.WriteLine(func.Compile()());
}

你不能。

反射不会扩展到读取方法变量的值。

它只处理变量的声明元数据。 即使如此,编译器可能已经删除了你认为你声明的变量。 你已经可以访问属性,字段。


不,你不能,因为这些变量在方法范围之外根本不可用。

链接地址: http://www.djcxy.com/p/92585.html

上一篇: How can i access the value of a local variable from within an expression tree

下一篇: Visual Studio Code not loading symbols on OS X