Składnia zapytania i metody w technologii LINQ (C#)Query Syntax and Method Syntax in LINQ (C#)

Większość zapytań w dokumentacji języka wprowadzającego Integrated QueryLINQLINQ() jest zapisywana przy użyciu składni zapytania deklaracyjnego LINQ.Most queries in the introductory Language Integrated Query (LINQLINQ) documentation are written by using the LINQ declarative query syntax. Jednak Składnia zapytania musi być przetłumaczona na wywołania metody dla środowiska uruchomieniowego języka wspólnego (CLR) platformy .NET podczas kompilowania kodu.However, the query syntax must be translated into method calls for the .NET common language runtime (CLR) when the code is compiled. Te wywołania metody wywołują standardowe operatory zapytań, które mają nazwy takie jak Where, Select, GroupBy, Join Max, i Average.These method calls invoke the standard query operators, which have names such as Where, Select, GroupBy, Join, Max, and Average. Można wywołać je bezpośrednio przy użyciu składni metody zamiast składni zapytania.You can call them directly by using method syntax instead of query syntax.

Składnia zapytań i składnia metody są semantycznie takie same, ale wiele osób może łatwiej odczytywać składnię zapytań.Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read. Niektóre zapytania muszą być wyrażone jako wywołania metod.Some queries must be expressed as method calls. Na przykład należy użyć wywołania metody, aby wyrazić zapytanie, które pobiera liczbę elementów zgodnych z określonym warunkiem.For example, you must use a method call to express a query that retrieves the number of elements that match a specified condition. Należy również użyć wywołania metody dla zapytania pobierającego element, który ma wartość maksymalną w sekwencji źródłowej.You also must use a method call for a query that retrieves the element that has the maximum value in a source sequence. Dokumentacja referencyjna dla standardowych operatorów zapytań w System.Linq przestrzeni nazw zwykle używa składni metody.The reference documentation for the standard query operators in the System.Linq namespace generally uses method syntax. W związku z tym nawet gdy zaczynasz pisać LINQLINQ zapytania, warto zapoznać się z tematem jak używać składni metody w zapytaniach i w samych wyrażeniach zapytania.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.

Metody rozszerzające standardowy operator zapytańStandard Query Operator Extension Methods

W poniższym przykładzie pokazano proste wyrażenie zapytania i semantycznie równoważne zapytanie zapisywane jako zapytanie opartena metodzie.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
 */

Dane wyjściowe z dwóch przykładów są identyczne.The output from the two examples is identical. Można zobaczyć, że typ zmiennej zapytania jest taka sama w obu formach: IEnumerable<T>.You can see that the type of the query variable is the same in both forms: IEnumerable<T>.

Aby zrozumieć zapytanie oparte na metodzie, Przeanalizujmy ją dokładniej.To understand the method-based query, let's examine it more closely. Po prawej stronie wyrażenia Zauważ, że where klauzula jest teraz wyrażona jako metoda wystąpienia numbers na obiekcie, co oznacza, że IEnumerable<int>odwołanie ma typ.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>. Jeśli znasz interfejs ogólny IEnumerable<T> , wiesz, że nie Where ma metody.If you are familiar with the generic IEnumerable<T> interface, you know that it does not have a Where method. Jeśli jednak zostanie wywołana lista uzupełniania IntelliSense w środowisku IDE programu Visual Where Studio, zobaczysz nie tylko metodę, ale wiele innych metod, takich jak Select, SelectMany Join, i 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. To są wszystkie standardowe operatory zapytań.These are all the standard query operators.

Zrzut ekranu przedstawiający wszystkie standardowe operatory zapytań w IntelliSense.

Mimo że został on IEnumerable<T> ponownie zdefiniowany w celu uwzględnienia tych dodatkowych metod, w rzeczywistości nie jest to przypadek.Although it looks as if IEnumerable<T> has been redefined to include these additional methods, in fact this is not the case. Standardowe operatory zapytań są implementowane jako nowy rodzaj metody wywoływanie metod rozszerzających.The standard query operators are implemented as a new kind of method called extension methods. Metody rozszerzeń "rozszerzają" istniejący typ; mogą być wywoływane tak, jakby były metodami wystąpień w typie.Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. Standardowe operatory zapytań zwiększają IEnumerable<T> się i dlatego można pisać. numbers.Where(...)The standard query operators extend IEnumerable<T> and that is why you can write numbers.Where(...).

Aby rozpocząć korzystanie z LINQLINQprogramu, wszystko, co naprawdę trzeba wiedzieć na temat metod rozszerzających, polega na tym, jak przenieść je do zakresu w aplikacji using za pomocą odpowiednich dyrektyw.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. Z punktu widzenia aplikacji Metoda rozszerzająca i zwykła metoda wystąpienia są takie same.From your application's point of view, an extension method and a regular instance method are the same.

Aby uzyskać więcej informacji na temat metod rozszerzających, zobacz metody rozszerzenia.For more information about extension methods, see Extension Methods. Aby uzyskać więcej informacji na temat standardowych operatorów zapytań, zobacz standardowe operatory zapytańC#— omówienie ().For more information about standard query operators, see Standard Query Operators Overview (C#). Niektórzy LINQLINQ dostawcy, takie jak LINQ do SQLLINQ to SQL i LINQ do XMLLINQ to XML, implementują własne standardowe operatory zapytań IEnumerable<T>i dodatkowe metody rozszerzające dla innych typów.Some LINQLINQ providers, such as LINQ do SQLLINQ to SQL and LINQ do XMLLINQ to XML, implement their own standard query operators and additional extension methods for other types besides IEnumerable<T>.

Wyrażenia lambdaLambda Expressions

W poprzednim przykładzie należy zauważyć, że wyrażenie warunkowe (num % 2 == 0) jest przekazywany jako argument w wierszu Where do metody: Where(num => num % 2 == 0).To wyrażenie wbudowane jest nazywane wyrażeniem 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. Jest to wygodny sposób pisania kodu, który w przeciwnym razie musi być napisany w bardziej skomplikowany sposób jako metoda anonimowa lub Delegat ogólny lub drzewo wyrażenia.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. W C# => programie jest operatorem lambda, który jest odczytywany jako "przechodzi do".In C# => is the lambda operator, which is read as "goes to". Po lewej stronie operatora jest zmienną wejściową, która odnosi się do num w wyrażeniu zapytania. numThe num on the left of the operator is the input variable which corresponds to num in the query expression. Kompilator może wywnioskować typ num , ponieważ wie, że numbers jest typem ogólnym. IEnumerable<T>The compiler can infer the type of num because it knows that numbers is a generic IEnumerable<T> type. Treść wyrażenia lambda jest taka sama jak wyrażenie w składni zapytania lub w dowolnym innym C# wyrażeniu lub instrukcji. może obejmować wywołania metod i inne złożone logiki.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. "Zwracana wartość" jest tylko wynikiem wyrażenia.The "return value" is just the expression result.

Aby rozpocząć korzystanie z LINQLINQprogramu, nie musisz używać wyrażeń lambda w szerokim stopniu.To get started using LINQLINQ, you do not have to use lambdas extensively. Jednak niektóre zapytania można wyrazić tylko w składni metody, a niektóre z nich wymagają wyrażenia lambda.However, certain queries can only be expressed in method syntax and some of those require lambda expressions. Po poznaniu się z wyrażeniami lambda można się dowiedzieć, że są one zaawansowanym i elastycznym narzędziem w LINQLINQ przyborniku.After you become more familiar with lambdas, you will find that they are a powerful and flexible tool in your LINQLINQ toolbox. Aby uzyskać więcej informacji, zobacz wyrażenia lambda.For more information, see Lambda Expressions.

Możliwości tworzenia zapytańComposability of Queries

W poprzednim przykładzie kodu należy zauważyć, że OrderBy Metoda jest wywoływana przy użyciu operatora kropki w Wherewywołaniu.In the previous code example, note that the OrderBy method is invoked by using the dot operator on the call to Where. Wheretworzy filtrowaną sekwencję, a następnie Orderby działa w tej sekwencji, sortując ją.Where produces a filtered sequence, and then Orderby operates on that sequence by sorting it. Ponieważ zapytania zwracają IEnumerable, należy je złożyć w składni metody przez łańcuch wywołań metod.Because queries return an IEnumerable, you compose them in method syntax by chaining the method calls together. Jest to działanie kompilatora w tle podczas pisania zapytań przy użyciu składni zapytania.This is what the compiler does behind the scenes when you write queries by using query syntax. A ponieważ zmienna zapytania nie przechowuje wyników zapytania, można je zmodyfikować lub użyć jako podstawy dla nowego zapytania w dowolnym momencie, nawet po jego wykonaniu.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.