exp = x => x.Name == person.Name && x.Age > 20; 像这样的字符串:-6ren">
gpt4 book ai didi

c# - 将包含变量的 Lambda 表达式转换为字符串

转载 作者:行者123 更新时间:2023-12-03 23:03:36 26 4
gpt4 key购买 nike

我想转换流动表达式

person.Name = "John";
Expression<Func<Person, bool>> exp = x => x.Name == person.Name && x.Age > 20;

像这样的字符串:

(x.Name == "John") AndAlso (x.Age > 20)

我使用exp.ToString();方法但结果是:

(x.Name == value(MyNamespace.MyClass+<>c__DisplayClass0).person.Name) AndAlso (x.Age > 20)

如何正确转换表达式?

最佳答案

问题是你的表达式引用了闭包范围内的变量,而你需要的是一个常量表达式。

您可以使用 ExpressionVisitor 重写表达式树,从而消除导致常量的成员访问:

namespace FixVisitor
{
class Program
{
static void Main(string[] args)
{
var person = new Person();
person.Name = "John";

Expression<Func<Person, bool>> exp = x => x.Name == person.Name && x.Age > 20;

var modified = new FixVisitor().Visit(exp);
Console.WriteLine(modified);
}
}

class FixVisitor : ExpressionVisitor
{
bool IsMemeberAccessOfAConstant(Expression exp)
{
if (exp.NodeType == ExpressionType.MemberAccess)
{
var memberAccess = (MemberExpression) exp;
if (memberAccess.Expression.NodeType == ExpressionType.Constant)
return true;
return IsMemeberAccessOfAConstant(memberAccess.Expression);
}

return false;
}

protected override Expression VisitMember(MemberExpression node)
{
if (IsMemeberAccessOfAConstant(node) && node.Type == typeof(string))
{
var item = Expression.Lambda<Func<string>>(node);
var value = item.Compile()();
return Expression.Constant(value, typeof(string));
}

return base.VisitMember(node);
}
}

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

public int Age { get; set; }
}
}

关于c# - 将包含变量的 Lambda 表达式转换为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32739639/

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