如何获取使用局部变量的ConstantExpression的值? [英] How to get the value of a ConstantExpression which uses a local variable?

查看:331
本文介绍了如何获取使用局部变量的ConstantExpression的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个ExpressionVisitor实现,该实现重写VisitConstant。但是,当我创建一个使用局部变量的表达式时,似乎无法获得该变量的实际值。

I created an ExpressionVisitor implementation that overrides VisitConstant. However, when I create an expression that utilizes a local variable I can't seem to get the actual value of the variable.

public class Person
{
  public string FirstName { get; set; }
}

string name = "Michael";

Expression<Func<Person, object>> exp = p => p.FirstName == name;

我如何从ConstantExpression中获得变量 name的值?
我唯一能想到的是:

How in the world do I get the value of the variable "name" from the ConstantExpression? The only thing that I can think of is this:

string fieldValue = value.GetType().GetFields().First().GetValue(value).ToString();

显然,这并不能使其变得非常灵活....

Obviously this doesn't lend itself to being very flexible though....

一个稍微复杂的例子如下:

A slightly more complicated example would be the following:

Person localPerson = new Person { FirstName = "Michael" };
Expression<Func<Person, object>> exp = p => p.FirstName == localPerson.FirstName;


推荐答案

下面是我列出的两种情况下的解决方案。

Here's how I solved it for both cases you listed.

基本上假设'=='的右侧可以被视为不带任何参数并返回值的函数,可以将其编译为C#委托并调用该值即可检索该值,而不必担心右侧的代码究竟会做什么。

Basically assuming that the right hand side of your '==' can be treated like a function that takes no arguments and returns a value, it can be compiled to a C# delegate and invoked to retrieve this value without worrying about exactly what the code on the right hand side does.

因此,基本示例代码在

class Visitor : ExpressionVisitor {

  protected override Expression VisitBinary( BinaryExpression node ) {

    var memberLeft = node.Left as MemberExpression;
    if ( memberLeft != null && memberLeft.Expression is ParameterExpression ) {

      var f = Expression.Lambda( node.Right ).Compile();
      var value = f.DynamicInvoke();
      }

    return base.VisitBinary( node );
    }
  }

它寻找一个二进制运算符,寻找 arg。 member == something,然后只是编译/求值右侧,对于这两个示例,您提供的结果都是字符串 Michael。

It looks for a binary op looking for "arg.member == something" then just compiles/evaluates the right hand side, and for both examples your provide the result is a string "Michael".

注意,如果您的右侧涉及使用lamda参数,例如

Note, this fails if your right hand side involved using the lamda argument like


p.FirstName == CallSomeFunc(p.FirstName)

p.FirstName == CallSomeFunc( p.FirstName )

这篇关于如何获取使用局部变量的ConstantExpression的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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