某些对象关系映射(ORM)框架(如LLBLGen)允许您为查询方法指定“谓词”参数,例如(简化一点):
var entities = adapter.FetchEntities(EntityType.Employee,
EmployeeFields.Salary > 50000);
第二个参数如何在C#语法上起作用?它看起来像一个lambda表达式,但它没有参数部分或“=>”。它是什么?可能需要Jon Skeet这个。
答案 0 :(得分:6)
如果您重载“>
”运算符以在特殊的“SuperDatabaseMapField
”类型上返回某种谓词对象,则可以执行此类操作。
那就是说,取代lambda表达式(并且如果必须解析表达式树)在各方面看起来都差得多。
答案 1 :(得分:2)
我同意mquander's
回答。这样的构造工作的原因是因为编译器评估表达式的方式。在这种情况下,对于LLBLGen,第二个参数需要一些可以计算为布尔值的东西(例如)。
运算符(+, - ,***,/)只是编译器用于构建语法树的表达式,它用于验证左侧和右侧表达式的某些组合在给定上下文(“+”)时是否有效。例如a
(字符串文字)+ 2.4
(浮点数)显然在C#中无效,编译器通过验证表达式(string) 来了解这一点( operator_add) (float)。
因此,为了做出如下工作的奇怪场景:
FetchEntities(EntityType.Employee,
EmployeeFields.Salary > ((EmployeeFields.DateOfBirth - 10) * 1.2) + 1024)
有必要重载运算符( - 和***和+)以返回一个新的“谓词”对象。
最终这样的语句将被翻译成以下语法树(“()”中的项目是用于此答案的表达式类型)
(BinaryComparison)
LeftSide: (Field_Reference) --> EmployeeFields.Salary
RightSide:
(MathematicOperator)
LeftSide:
(MathematicOperator)
LeftSide:
(MathematicOperator)
LeftSide: (Field_Reference) --> EmployeeFields.DateOfBirth
RightSide: (constant) --> 10
Operator: --> -
RightSide: (constant) --> 1.2
Operator: --> ***
RightSide: (constant) --> 1024
Operator: --> +
Operator: --> >
这是关于lambda表达式和流畅查询的工作原理的全部基础。这一切都归结为表达评估。
Lambda表达式更具有表现力,因为它们可以触摸对象及其字段,属性和方法,并允许形成任意长度的语法树。