Abfragesyntax und Methodensyntax in LINQ (C#)Query Syntax and Method Syntax in LINQ (C#)

Die meisten Abfragen in der einführenden Dokumentation der Language Integrated Query (LINQLINQ) wurden mithilfe der deklarierten Abfragesyntax von LINQ geschrieben.Most queries in the introductory Language Integrated Query (LINQLINQ) documentation are written by using the LINQ declarative query syntax. Die Abfragesyntax muss jedoch in Methodenaufrufe für die .NET Common Language Runtime (CLR) übersetzt werden, wenn der Code kompiliert wird.However, the query syntax must be translated into method calls for the .NET common language runtime (CLR) when the code is compiled. Diese Methodenaufrufe rufen die Standardabfrageoperatoren auf, die z.B. folgende Namen haben: Where, Select, GroupBy, Join, Max und Average.These method calls invoke the standard query operators, which have names such as Where, Select, GroupBy, Join, Max, and Average. Sie können sie direkt mithilfe der Methodensyntax anstatt der Abfragesyntax aufrufen.You can call them directly by using method syntax instead of query syntax.

Abfragesyntax und Methodensyntax sind semantisch identisch, aber viele Benutzer finden die Abfragesyntax einfacher und leichter zu lesen.Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read. Einige Abfragen müssen als Methodenaufrufe ausgedrückt werden.Some queries must be expressed as method calls. Sie müssen z.B. einen Methodenaufruf verwenden, um eine Abfrage auszudrücken, die die Anzahl der Elemente abruft, die einer angegebenen Bedingung entsprechen.For example, you must use a method call to express a query that retrieves the number of elements that match a specified condition. Sie müssen einen Methodenaufruf auch für eine Abfrage verwenden, die das Element abruft, das den Maximalwert in der Quellsequenz hat.You also must use a method call for a query that retrieves the element that has the maximum value in a source sequence. In der Referenzdokumentation für die Standardabfrageoperatoren im System.Linq-Namespace wird im Allgemeinen die Methodensyntax verwendet.The reference documentation for the standard query operators in the System.Linq namespace generally uses method syntax. Daher ist es sinnvoll, sich mit der Verwendung der Methodensyntax in Abfragen und Abfrageausdrücken selbst vertraut zu machen, auch wenn man mit dem Schreiben von LINQLINQ-Abfragen beginnt.Therefore, even when getting started writing LINQLINQ queries, it is useful to be familiar with how to use method syntax in queries and in query expressions themselves.

Erweiterungsmethoden von StandardabfrageoperatorenStandard Query Operator Extension Methods

Im folgenden Beispiel wird ein einfacher Abfrageausdruck und die semantisch äquivalente Abfrage gezeigt, die als methodenbasierte Abfrage geschrieben ist.The following example shows a simple query expression and the semantically equivalent query written as a method-based query.

class QueryVMethodSyntax
{
    static void Main()
    {
        int[] numbers = { 5, 10, 8, 3, 6, 12};

        //Query syntax:
        IEnumerable<int> numQuery1 = 
            from num in numbers
            where num % 2 == 0
            orderby num
            select num;

        //Method syntax:
        IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

        foreach (int i in numQuery1)
        {
            Console.Write(i + " ");
        }
        Console.WriteLine(System.Environment.NewLine);
        foreach (int i in numQuery2)
        {
            Console.Write(i + " ");
        }
        
        // Keep the console open in debug mode.
        Console.WriteLine(System.Environment.NewLine);
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}
/*
    Output:
    6 8 10 12
    6 8 10 12
 */

Die Ausgabe der beiden Beispiele ist identisch.The output from the two examples is identical. Sie sehen, dass der Typ der Abfragevariable in beiden Formen der gleiche ist: IEnumerable<T>.You can see that the type of the query variable is the same in both forms: IEnumerable<T>.

Betrachten Sie die methodenbasierte Abfrage genauer, um sie besser zu verstehen.To understand the method-based query, let's examine it more closely. Beachten Sie, dass die where-Klausel auf der rechten Seite des Ausdrucks jetzt als Instanzmethode des numbers-Objekts ausgedrückt wird. Sie erinnern sich sicher, dass diese über einen IEnumerable<int>-Typ verfügt.On the right side of the expression, notice that the where clause is now expressed as an instance method on the numbers object, which as you will recall has a type of IEnumerable<int>. Wenn Sie mit der generischen IEnumerable<T>-Schnittstelle vertraut sind, wissen Sie, dass sie über keine Where-Methode verfügt.If you are familiar with the generic IEnumerable<T> interface, you know that it does not have a Where method. Wenn Sie jedoch die IntelliSense-Vervollständigungsliste in der Visual Studio IDE aufrufen, sehen Sie nicht nur eine Where-Methode, sondern viele andere Methoden, z.B. Select, SelectMany, Join und Orderby.However, if you invoke the IntelliSense completion list in the Visual Studio IDE, you will see not only a Where method, but many other methods such as Select, SelectMany, Join, and Orderby. Sie sind alle Standardabfrageoperatoren.These are all the standard query operators.

Standardabfrageoperatoren in IntellisenseStandard Query Operators in Intellisense

Obwohl es so scheint, als sei IEnumerable<T> neu definiert worden, um diese zusätzlichen Methoden zu enthalten, ist dies tatsächlich nicht der Fall.Although it looks as if IEnumerable<T> has been redefined to include these additional methods, in fact this is not the case. Die Standardabfrageoperatoren werden als eine neue Methodenart, die als Erweiterungsmethoden bezeichnet werden, implementiert.The standard query operators are implemented as a new kind of method called extension methods. Erweiterungsmethoden „erweitern“ einen vorhandenen Typ; sie können aufgerufen werden, als wären sie Instanzmethoden für den Typ.Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. Die Standardabfrageoperatoren erweitern IEnumerable<T>, weshalb Sie numbers.Where(...) schreiben können.The standard query operators extend IEnumerable<T> and that is why you can write numbers.Where(...).

Um mit der Verwendung von LINQLINQ zu beginnen, müssen Sie nur wissen, wie Sie Erweiterungsmethoden in Ihrer Anwendung mithilfe der richtigen using-Anweisungen in den Geltungsbereich einbinden können.To get started using LINQLINQ, all that you really have to know about extension methods is how to bring them into scope in your application by using the correct using directives. Aus Sicht Ihrer Anwendung sind eine Erweiterungsmethode und eine reguläre Instanzmethode identisch.From your application's point of view, an extension method and a regular instance method are the same.

Weitere Informationen zu Erweiterungsmethoden finden Sie unter Extension Methods (Erweiterungsmethoden).For more information about extension methods, see Extension Methods. Weitere Informationen über Standardabfrageoperatoren finden Sie unter Standard Query Operators Overview (C#) (Übersicht über Standardabfrageoperatoren (C#)).For more information about standard query operators, see Standard Query Operators Overview (C#). Einige LINQLINQ-Anbieter, z.B. LINQ to SQLLINQ to SQL und LINQ to XMLLINQ to XML, implementieren ihre eigenen Standardabfrageoperatoren und zusätzliche Erweiterungsmethoden für andere Typen neben IEnumerable<T>.Some LINQLINQ providers, such as LINQ to SQLLINQ to SQL and LINQ to XMLLINQ to XML, implement their own standard query operators and additional extension methods for other types besides IEnumerable<T>.

Lambda-AusdrückeLambda Expressions

Beachten Sie im vorherigen Beispiel, dass der bedingte Ausdruck num % 2 == 0 als Inlineargument an die Where-Methode übergeben wird: Where(num => num % 2 == 0).. Dieser Inlineausdruck wird als Lambdaausdruck bezeichnet.In the previous example, notice that the conditional expression (num % 2 == 0) is passed as an in-line argument to the Where method: Where(num => num % 2 == 0). This inline expression is called a lambda expression. Dies ist eine einfache Möglichkeit, Code zu schreiben, der sonst auf einem unpraktischeren Weg als anonyme Methode, generischer Delegat oder Ausdrucksbaumstruktur geschrieben werden müsste.It is a convenient way to write code that would otherwise have to be written in more cumbersome form as an anonymous method or a generic delegate or an expression tree. In C# ist der Lambdaoperator =>, der als „wird zu“ gelesen wird.In C# => is the lambda operator, which is read as "goes to". num auf der linken Seite des Operators ist die Eingabevariable, die num im Eingabeausdruck entspricht.The num on the left of the operator is the input variable which corresponds to num in the query expression. Der Compiler kann den Typ von num ableiten, da er weiß, dass es sich bei numbers um einen generischen IEnumerable<T>-Typ handelt.The compiler can infer the type of num because it knows that numbers is a generic IEnumerable<T> type. Der Text des Lambdaausdrucks entspricht genau dem Ausdruck in der Abfragesyntax, in einem anderen Ausdruck oder in einer Anweisung in C#; er kann Methodenaufrufe und andere komplexe Logik enthalten.The body of the lambda is just the same as the expression in query syntax or in any other C# expression or statement; it can include method calls and other complex logic. Der „Rückgabewert“ ist nur das Ergebnis des Ausdrucks.The "return value" is just the expression result.

Sie müssen Lambdaausdrücke nicht häufig verwenden, wenn Sie mit der Verwendung von LINQLINQ beginnen.To get started using LINQLINQ, you do not have to use lambdas extensively. Allerdings können bestimme Abfragen nur in der Methodensyntax ausgedrückt werden, und einige von ihnen benötigen Lambdaausdrücke.However, certain queries can only be expressed in method syntax and some of those require lambda expressions. Wenn Sie sich mit Lambdaausdrücken besser vertraut gemacht haben, werden Sie sehen, dass sie ein leistungsstarkes und flexibles Tool in Ihrer LINQLINQ-Toolbox sind.After you become more familiar with lambdas, you will find that they are a powerful and flexible tool in your LINQLINQ toolbox. Weitere Informationen finden Sie unter Lambdaausdrücke.For more information, see Lambda Expressions.

Zusammensetzbarkeit von AbfragenComposability of Queries

Beachten Sie im vorherigen Codebeispiel, dass die OrderBy-Methode durch Verwendung des Punktoperators auf dem Aufruf von Where aufgerufen wird.In the previous code example, note that the OrderBy method is invoked by using the dot operator on the call to Where. Where erzeugt eine gefilterte Sequenz, und Orderby bearbeitet sie anschließend durch Sortierung.Where produces a filtered sequence, and then Orderby operates on that sequence by sorting it. Da Abfragen IEnumerable zurückgeben, erstellen Sie sie in der Methodensyntax durch Verkettung von Methodenaufrufen miteinander.Because queries return an IEnumerable, you compose them in method syntax by chaining the method calls together. Das führt auch der Compiler im Hintergrund aus, wenn Sie über die Abfragesyntax Abfragen erstellen.This is what the compiler does behind the scenes when you write queries by using query syntax. Da die Abfragevariable die Ergebnisse der Abfrage nicht speichert, können Sie sie jederzeit ändern oder als Basis für eine neue Abfrage verwenden, sogar, wenn sie bereits ausgeführt wurde.And because a query variable does not store the results of the query, you can modify it or use it as the basis for a new query at any time, even after it has been executed.

Siehe auchSee Also

Erste Schritte mit LINQ in C#Getting Started with LINQ in C#