Syntaxe de requête et syntaxe de méthode dans LINQ (C#)Query Syntax and Method Syntax in LINQ (C#)

La plupart des requêtes de la documentation de présentation de Langage Integrated Query (LINQLINQ) sont écrites à l’aide de la syntaxe de requête déclarative de LINQ.Most queries in the introductory Language Integrated Query (LINQLINQ) documentation are written by using the LINQ declarative query syntax. Toutefois, la syntaxe de requête doit être traduite en appels de méthode pour le Common Langage Runtime (CLR) .NET lorsque le code est compilé.However, the query syntax must be translated into method calls for the .NET common language runtime (CLR) when the code is compiled. Ces appels de méthode appellent les opérateurs de requête standard, qui ont des noms tels que Where, Select, GroupBy, Join, Max et Average.These method calls invoke the standard query operators, which have names such as Where, Select, GroupBy, Join, Max, and Average. Vous pouvez les appeler directement en utilisant la syntaxe de méthode à la place de la syntaxe de requête.You can call them directly by using method syntax instead of query syntax.

La syntaxe de requête et la syntaxe de méthode sont identiques sémantiquement, mais de nombreuses personnes trouvent la syntaxe de requête plus simple et plus facile à lire.Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read. Certaines requêtes doivent être exprimées en tant qu’appels de méthode.Some queries must be expressed as method calls. Par exemple, vous devez utiliser un appel de méthode pour exprimer une requête qui récupère le nombre d’éléments qui correspondent à une condition spécifiée.For example, you must use a method call to express a query that retrieves the number of elements that match a specified condition. Vous devez également utiliser un appel de méthode pour une requête qui récupère dans une séquence source l’élément qui a la valeur maximale.You also must use a method call for a query that retrieves the element that has the maximum value in a source sequence. En général, la documentation de référence des opérateurs de requête standard dans l’espace de noms System.Linq utilise la syntaxe de méthode.The reference documentation for the standard query operators in the System.Linq namespace generally uses method syntax. Par conséquent, même lorsque vous commencez à écrire des requêtes LINQLINQ, il est utile de se familiariser avec l’utilisation de la syntaxe de méthode dans les requêtes et dans les expressions de requête elles-mêmes.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.

Méthodes d’extension d’opérateur de requête standardStandard Query Operator Extension Methods

L’exemple suivant présente une expression de requête simple et la requête sémantiquement équivalente écrite en tant que requête fondée sur une méthode.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
 */

La sortie des deux exemples est identique.The output from the two examples is identical. Vous pouvez voir que le type de la variable de requête est le même dans les deux formes : IEnumerable<T>.You can see that the type of the query variable is the same in both forms: IEnumerable<T>.

Pour comprendre la requête basée sur une méthode, examinons-la de plus près.To understand the method-based query, let's examine it more closely. Du côté droit de l’expression, remarquez que la clause where est maintenant exprimée comme une méthode d’instance sur l’objet numbers, qui, comme vous vous en rappelez, a un type IEnumerable<int>.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>. Si vous êtes connaissez bien l’interface IEnumerable<T> générique, vous savez qu’elle n’a pas de méthode Where.If you are familiar with the generic IEnumerable<T> interface, you know that it does not have a Where method. Toutefois, si vous appelez la liste de saisie semi-automatique IntelliSense dans l’IDE de Visual Studio, vous ne verrez pas seulement une méthode Where, mais de nombreuses autres méthodes telles que Select, SelectMany, Join et 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. Il s’agit de tous les opérateurs de requête standard.These are all the standard query operators.

Capture d’écran montrant tous les opérateurs de requête standard dans Intellisense.

Même s’il semble que IEnumerable<T> a été redéfini pour inclure ces méthodes supplémentaires, ce n’est pas le cas, en réalité.Although it looks as if IEnumerable<T> has been redefined to include these additional methods, in fact this is not the case. Les opérateurs de requête standard sont implémentés comme un nouveau type de méthode, appelé méthodes d’extension.The standard query operators are implemented as a new kind of method called extension methods. Les méthodes d’extension « étendent » un type existant. Elles peuvent être appelées comme s’il s’agissait de méthodes d’instance sur le type.Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. Les opérateurs de requête standard étendent IEnumerable<T>, si bien que vous pouvez écrire numbers.Where(...).The standard query operators extend IEnumerable<T> and that is why you can write numbers.Where(...).

Pour commencer à utiliser LINQLINQ, tout ce que vous devez savoir sur les méthodes d’extension est la façon de les mettre à portée de votre application à l’aide des directives using appropriées.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. Du point de vue de votre application, une méthode d’extension et une méthode d’instance normale sont identiques.From your application's point of view, an extension method and a regular instance method are the same.

Pour plus d’informations sur les méthodes d’extension, consultez Méthodes d’extension.For more information about extension methods, see Extension Methods. Pour plus d’informations sur les opérateurs de requête standard, consultez Présentation des opérateurs de requête standard (C#).For more information about standard query operators, see Standard Query Operators Overview (C#). Certains fournisseurs LINQLINQ, tels que LINQ to SQLLINQ to SQL et LINQ to XMLLINQ to XML, implémentent leurs propres opérateurs de requête standard et des méthodes d’extension supplémentaires pour d’autres types que 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>.

Expressions lambdaLambda Expressions

Dans l’exemple précédent, notez que l’expression conditionnelle (num % 2 == 0) est passée comme argument de ligne à la méthode Where : Where(num => num % 2 == 0). Cette expression incluse est appelée expression lambda.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. C’est un moyen pratique d’écrire du code qui devrait autrement être écrit sous une forme plus fastidieuse, comme une méthode anonyme, un délégué générique ou une arborescence d’expressions.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. En C#, => est l’opérateur lambda, qui se lit « conduit à ».In C# => is the lambda operator, which is read as "goes to". Le num situé à gauche de l’opérateur est la variable d’entrée qui correspond à num dans l’expression de requête.The num on the left of the operator is the input variable which corresponds to num in the query expression. Le compilateur peut déduire le type de num, car il sait que numbers est un type IEnumerable<T> générique.The compiler can infer the type of num because it knows that numbers is a generic IEnumerable<T> type. Le corps de l’expression lambda est identique à l’expression dans la syntaxe de requête ou dans toute autre expression ou instruction C#. Il peut inclure des appels de méthode et une autre logique complexe.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. La « valeur de retour » est simplement le résultat de l’expression.The "return value" is just the expression result.

Vous n’avez pas besoin d’utiliser fréquemment les expressions lambda pour commencer à utiliser LINQLINQ.To get started using LINQLINQ, you do not have to use lambdas extensively. Toutefois, certaines requêtes peuvent être exprimées uniquement dans la syntaxe de méthode. Parmi elles, certaines nécessitent des expressions lambda.However, certain queries can only be expressed in method syntax and some of those require lambda expressions. Une fois que vous serez plus familiarisé avec les expressions lambda, vous constaterez qu’elles sont un outil puissant et flexible dans votre boîte à outils LINQLINQ.After you become more familiar with lambdas, you will find that they are a powerful and flexible tool in your LINQLINQ toolbox. Pour plus d’informations, voir Expressions lambda.For more information, see Lambda Expressions.

Composabilité des requêtesComposability of Queries

Dans l’exemple de code précédent, notez que la méthode OrderBy est appelée à l’aide de l’opérateur point sur l’appel à Where.In the previous code example, note that the OrderBy method is invoked by using the dot operator on the call to Where. Where produit une séquence filtrée, puis Orderby agit sur cette séquence en la triant.Where produces a filtered sequence, and then Orderby operates on that sequence by sorting it. Étant donné que les requêtes retournent un IEnumerable, vous les composez dans la syntaxe de méthode en chaînant les appels de méthode ensemble.Because queries return an IEnumerable, you compose them in method syntax by chaining the method calls together. Le compilateur effectue cette opération en arrière-plan lorsque vous écrivez des requêtes à l’aide de la syntaxe de requête.This is what the compiler does behind the scenes when you write queries by using query syntax. De plus, étant donné qu’une variable de requête ne stocke pas les résultats de la requête, vous pouvez la modifier ou l’utiliser à tout moment comme base d’une nouvelle requête, même après son exécution.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.

Voir aussiSee also