gpt4 book ai didi

c# - 如何获取使用局部变量的 ConstantExpression 的值?

转载 作者:IT王子 更新时间:2023-10-29 04:46:11 26 4
gpt4 key购买 nike

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

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

string name = "Michael";

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

究竟如何从 ConstantExpression 中获取变量“name”的值?我唯一能想到的是:

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

显然这并不适合非常灵活......

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

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

最佳答案

编辑:好的,由于 AHM 的评论,现在您的意思更清楚了。

基本上,代码被编译为在单独的类中捕获 name - 然后应用字段访问以从引用它的实例的常量表达式中获取其值。 (它必须这样做,因为您可以在创建表达式后更改 name 的值 - 但表达式捕获变量,而不是值。)

所以您实际上不想对 VisitConstant 中的 ConstantExpression 做任何事情 - 您想要处理 VisitMember 中的字段访问.您需要从 ConstantExpression 子项中获取值,然后将其提供给 FieldInfo 以获取值:

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

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

static class Program
{
static void Main(string[] args)
{
string name = "Michael";

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

new Visitor().Visit(exp);
}
}

class Visitor : ExpressionVisitor
{
protected override Expression VisitMember
(MemberExpression member)
{
if (member.Expression is ConstantExpression &&
member.Member is FieldInfo)
{
object container =
((ConstantExpression)member.Expression).Value;
object value = ((FieldInfo)member.Member).GetValue(container);
Console.WriteLine("Got value: {0}", value);
}
return base.VisitMember(member);
}
}

编辑:好吧,稍微复杂一点的访问者类:

class Visitor : ExpressionVisitor    
{
protected override Expression VisitMember
(MemberExpression memberExpression)
{
// Recurse down to see if we can simplify...
var expression = Visit(memberExpression.Expression);

// If we've ended up with a constant, and it's a property or a field,
// we can simplify ourselves to a constant
if (expression is ConstantExpression)
{
object container = ((ConstantExpression) expression).Value;
var member = memberExpression.Member;
if (member is FieldInfo)
{
object value = ((FieldInfo)member).GetValue(container);
return Expression.Constant(value);
}
if (member is PropertyInfo)
{
object value = ((PropertyInfo)member).GetValue(container, null);
return Expression.Constant(value);
}
}
return base.VisitMember(memberExpression);
}
}

现在运行它:

var localPerson = new Person { FirstName = "Jon" };

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

Console.WriteLine("Before: {0}", exp);
Console.WriteLine("After: {0}", new Visitor().Visit(exp));

给出结果:

Before: p => Convert((p.FirstName == 
value(Program+<>c__DisplayClass1).localPerson.FirstName))
After: p => Convert((p.FirstName == "Jon"))

关于c# - 如何获取使用局部变量的 ConstantExpression 的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6998523/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com