2009-08-10 51 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表達式更具有表達性,因爲它們可以觸及對象及其字段,屬性和方法,並允許形成任意長度的語法樹。