3

一部のオブジェクト リレーショナル マッピング (ORM) フレームワーク (LLBLGen など) では、次のようなクエリ メソッドに「述語」パラメーターを指定できます。

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

その 2 番目のパラメーターは、C# で構文的にどのように機能しますか? ラムダ式のように見えますが、パラメータ部分や「=>」がありません。それは何ですか?これにはジョン・スキートが必要かもしれません。

4

2 に答える 2

6

" " 演算子をオーバーロード>して、特殊な型である種の述語オブジェクトを返すSuperDatabaseMapField場合は、そのようなことができます。

とはいえ、代わりにラムダ式を使用する (必要に応じて式ツリーを解析する) よりも、あらゆる点で非常に劣っているようです。

于 2009-08-10T21:30:08.663 に答える
2

私は答えに同意しmquander'sます。このような構成が機能する理由は、コンパイラが式を評価する方法によるものです。この場合、LLBLGen の場合、2 番目のパラメーターはブール値に評価できるもの (たとえば) を想定しています。

演算子 (+、-、​​**、/) は、コンテキスト ("+") が与えられた場合に左式と右式の特定の組み合わせが有効かどうかを検証するために使用する構文ツリーを構築するためにコンパイラが使用する単なる式です。たとえば、a(stringliteral) + 2.4(float) は 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:     --> >

これは、ラムダ式や流れるようなクエリがどのように機能するかの全体的な基礎です。それはすべて式の評価に要約されます。

ラムダ式は、オブジェクトとそのフィールド、プロパティ、メソッドに触れ、任意の長さの構文ツリーを形成できるという点で、より表現力があります。

于 2009-08-10T21:57:27.250 に答える