如何获取使用局部变量的ConstantExpression的值? [英] How to get the value of a ConstantExpression which uses a local variable?
问题描述
我创建了一个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屋!