所以从表达式的角度来看,值是一个常数。它不能被表达式改变。
你所拥有的是一个潜在的开放闭包 - 即值可以在表达式的执行之间发生变化,但在执行期间不会发生变化。所以它是一个“常数”。这是函数式编程和非函数式编程世界之间的范式差异:) 编程。
考虑
int a =2;
Expression<Func<int, int>> h = x=> x+ a;
Expression<Func<int, int>> j = x => x +2;
a = 1;
术语 a 是匿名类的成员访问,它封装并访问堆栈上的 a 变量。第一个节点是 MemberAccess 节点,然后在其下方 - 表达式是一个常量。
对于上面的代码:
((SimpleBinaryExpression)(h.Body)).Right
{value(WindowsFormsApplication6.Form1+<>c__DisplayClass0).a}
CanReduce: false
DebugView: ".Constant<WindowsFormsApplication6.Form1+<>c__DisplayClass0>(WindowsFormsApplication6.Form1+<>c__DisplayClass0).a"
Expression: {value(WindowsFormsApplication6.Form1+<>c__DisplayClass0)}
Member: {Int32 a}
NodeType: MemberAccess
Type: {Name = "Int32" FullName = "System.Int32"}
下面的常量:
((MemberExpression)((SimpleBinaryExpression)(h.Body)).Right).Expression
{value(WindowsFormsApplication6.Form1+<>c__DisplayClass0)}
CanReduce: false
DebugView: ".Constant<WindowsFormsApplication6.Form1+<>c__DisplayClass0>(WindowsFormsApplication6.Form1+<>c__DisplayClass0)"
NodeType: Constant
Type: {Name = "<>c__DisplayClass0" FullName = "WindowsFormsApplication6.Form1+<>c__DisplayClass0"}
Value: {WindowsFormsApplication6.Form1.}
}
}
普通的旧 2 出现在:
((SimpleBinaryExpression)(j.Body)).Right
{2}
CanReduce: false
DebugView: "2"
NodeType: Constant
Type: {Name = "Int32" FullName = "System.Int32"}
Value: 2
所以我不知道这是否对你有帮助。您可以通过查看父节点或父节点访问的对象类型来判断。
根据您的说明添加 -
所以当你说
user => user.Email == email
您的意思是查找所有电子邮件等于传入参数的用户 - 但是该链接表达式的含义完全不同。
你想说的是
Expression<Func<User, string, bool>> (user, email) => user.Email == email
这样,电子邮件现在将成为一个参数。如果你不喜欢这样,你可以做另一件事。
第二个例子可以正常工作 - 不需要额外的参数 consts 将是 consts。
t => t.Status != TaskStatus.Done && t.Status != TaskStatus.Failed
编辑:添加另一种方式:
因此,要使代码正常工作,您必须做的一件事是在 lambda 之外声明一个字符串电子邮件 - 这有点笨拙。
您可以通过将参数放在特定位置(如静态类)来更好地识别参数。然后,当通过 Lambda 时,您不必看一些可怕的 cloture 对象——而是您制作的一个不错的静态类。
public static class Parameter
{
public static T Input<T>(string name)
{
return default(T);
}
}
那么你的代码如下所示:
Expression<Func<User, bool>> exp = x => x.Email == Parameter.Input<String>("email");
然后您可以遍历树 - 当您调用 Parameter 静态类时,您可以查看类型和名称(在参数集合中)然后继续......