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

标签 c# lambda

我想转换流动表达式

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/

相关文章:

javascript - window.setTimeout ('window.location="http ://www. example.com"; ', 2000); 在代码后面

c# - 注入(inject) InSingletonScope 的对象是否也可以注入(inject)到其他地方的多重绑定(bind)中?

c# - 无法使用字典反序列化 json 对象

c# - 当一个变量被关闭两次时,它存储在哪里?

java - 无法在不指定类型参数的情况下将 Java 8 方法与 lambda 参数一起使用

c# - 如何使用 LINQ 将基类对象的集合转换为它们各自子类的过滤列表?

node.js - Aws Lambda 响应错误

c# - Prolog 与 C# Visual Studio 13

c# - 从 winform 应用程序中的 Combobox 读取值

java - 流利的 API 打破了类型推断