3 Stimmen

Wie funktionieren Prädikatsparameter syntaktisch in C#?

Einige Object Relational Mapping (ORM)-Frameworks (z. B. LLBLGen) ermöglichen die Angabe von "Prädikat"-Parametern für die Abfragemethoden, wie z. B. (etwas vereinfacht):

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

Wie funktioniert dieser 2. Parameter syntaktisch in C#? Es sieht irgendwie aus wie ein Lambda-Ausdruck, aber es hat nicht den Parameter Teil oder die "=>". Was ist das? Ich brauche vielleicht Jon Skeet für diese Frage.

6voto

mqp Punkte 66863

Wenn Sie den "" überladen haben > "Operator, um eine Art Prädikatsobjekt für Ihr spezielles " SuperDatabaseMapField "Typus könnten Sie solche Dinge tun.

Das heißt, es scheint in jeder Hinsicht weit unterlegen zu sein, wenn man stattdessen einen Lambda-Ausdruck nimmt (und einen Ausdrucksbaum analysiert, wenn man das muss).

2voto

Mike J Punkte 2961

Ich stimme zu mit mquander's Antwort. Der Grund, warum ein solches Konstrukt funktioniert, liegt in der Art und Weise, wie Compiler Ausdrücke auswerten. In diesem Fall für LLBLGen erwartet der zweite Parameter etwas, das als Boolean ausgewertet werden kann (zum Beispiel).

Operatoren (+, -, ***, /) sind lediglich Ausdrücke, die der Compiler verwendet, um Syntaxbäume zu erstellen, anhand derer er prüft, ob bestimmte Kombinationen von linken und rechten Ausdrücken im jeweiligen Kontext ("+") gültig sind. Zum Beispiel a (String-Literal) + 2.4 (float) ist in C# offensichtlich nicht gültig, und der Compiler weiß dies durch die Validierung der Ausdrücke (Zeichenfolge) (operator_add) (Schwimmer) .

Damit ein seltsames Szenario wie das folgende funktionieren kann, müssen Sie also

FetchEntities(EntityType.Employee, 
    EmployeeFields.Salary > ((EmployeeFields.DateOfBirth - 10) * 1.2) + 1024)

wäre es notwendig, die Operatoren (- und *** und +) zu überladen, um ein neues "Prädikat"-Objekt zurückzugeben.

Letztendlich würde eine solche Aussage in den folgenden Syntaxbaum übersetzt werden (die Elemente in "()" sind Ausdruckstypen für die Zwecke dieser Antwort)

(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:     --> >

Dies ist die gesamte Grundlage dafür, wie Dinge wie Lambda-Ausdrücke und fließende Abfragen funktionieren. Es läuft alles auf die Auswertung von Ausdrücken hinaus.

Lambda-Ausdrücke sind insofern ausdrucksstärker, als sie Objekte und deren Felder, Eigenschaften und Methoden berühren können und die Bildung eines Syntaxbaums beliebiger Länge ermöglichen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X