我想将linq Expression(Expression \\>)编译成字符串。
这很好用:
Expression<Func<MyTestClass, bool>> q5 = x => x.Prop1 == "abc" || x.Prop2 == 123;
通过调用q5.Body.ToString()得到预期的输出:
((x.Prop1 ==“abc”)OrElse(x.Prop2 == 123))
但是当我用更复杂的值替换任何BinaryExpression的右边部分时,问题就开始了。例如:
var item = new MyTestClass {Prop2 = 123};
var prop2 = 23;
string prop = "abc";
Expression<Func<MyTestClass, bool>> q5 = x => x.Prop1 == prop || x.Prop2 == item.Prop2;
输出变为:
((x.Prop1 == value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0_0).prop)OrElse(x.Prop2 == value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0_0).item.Prop2))
我或多或少地理解为什么Expression会编译成这个并且我可能需要通过查找MemberExpression类型并评估成员值来遍历所有表达式部分,但是这是一种更简单的方法来获得类似于第一个示例中的类似内容? 我需要的是用它的值替换'value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0_0).item.Prop2)'。
谢谢
答案 0 :(得分:0)
没有。 item
是引用类型,必须在运行时解析。如果您稍后设置item.Prop2 = 456
该怎么办?编译器不知道何时将评估q5,所以如果你要运行
Expression<Func<MyTestClass, bool>> q5 = x => x.Prop1 == prop || x.Prop2 == item.Prop2;
Console.WriteLine(q5.Body);
item.Prop2 = 456;
Console.WriteLine(q5.Body);
你会得到两个相同的
((x.Prop1 == value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0).prop)OrElse(x.Prop2 = = value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0).item.Prop2))
通过在lambda中保留值类型,编译器知道它不会发生变化,并且无论何时进行评估,它都将始终检查"abc"
和123
。