2009-08-10 55 views
3

有些对象关系映射(ORM)框架(如LLBLGEN)允许您指定“上游”参数的查询方法,如(简化了一下):谓词参数如何在C#中进行语法工作?

var entities = adapter.FetchEntities(EntityType.Employee, 
    EmployeeFields.Salary > 50000); 

这是如何第2个参数的工作语法在C#中?它看起来像一个lambda表达式,但它没有参数部分或“=>”。它是什么?这可能需要Jon Skeet。

+0

有人猜测,某种操作符重载? – spender 2009-08-10 21:28:54

回答

6

如果您重载了“>”运算符来返回特殊“SuperDatabaseMapField”类型的某种谓词对象,则可以执行此类操作。

这就是说,它(如果你要和解析表达式目录树。)似乎在各方面都采取lambda表达式,而不是远比不上

+0

是的,我一直认为,运营商在这种程度上变态的程度通常会以混乱而告终,正如OP所表明的那样。 – spender 2009-08-10 21:34:05

2

我同意mquander's答案。这种结构的工作原因是编译器评估表达式的方式。在这种情况下,对于LLBLGen,第二个参数需要某些可以评估为布尔值(例如)的东西。

运算符(+, - ,***,/)仅仅是表达式,编译器用它来构建语法树,它用于验证在给定上下文(“+”)的情况下,左右表达式的某些组合是否有效。例如a(字符串字面量)+ 2.4(浮动)显然不是在C#有效,并且编译器知道该从验证表达式(串)(operator_add)(浮动)

因此,为了使一个奇怪的场景一样了以下工作:

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表达式更具有表达性,因为它们可以触及对象及其字段,属性和方法,并允许形成任意长度的语法树。