Compartilhar via


Sintaxe de consulta do LINQ em comparação com a sintaxe do método (C#)

A maioria das consultas no introdutório LINQ documentação são gravados como expressões de consulta usando a sintaxe de consulta declarativa introduzida no C# 3.0. No entanto, o.NET common language runtime (CLR) não tem noção de sintaxe de consulta em si. Portanto, em tempo de compilação, expressões de consulta são traduzidas para algo que o CLR entender: chamadas de método. Esses métodos são chamados de operadores de consulta padrão, e eles têm nomes como Where, Select, GroupBy, Join, Max, Average, e assim por diante. Você pode chamá-los diretamente, usando a sintaxe do método em vez da sintaxe de consulta.

Em geral, recomendamos que a sintaxe de consulta porque ele é geralmente mais simples e mais legíveis; No entanto não há nenhuma diferença semântica entre a sintaxe do método e a sintaxe de consulta. Além disso, algumas consultas, tais como aqueles que recuperar o número de elementos que correspondam a uma condição especificada, ou que recuperar o elemento que possui o valor máximo em uma seqüência de origem, só pode ser expresso como chamadas de método. A documentação de referência para os operadores de consulta padrão a System.Linq geralmente usa um namespace sintaxe do método. Portanto, mesmo quando guia de Introdução à escrita LINQ consultas, é útil estar familiarizado com o uso de sintaxe do método em consultas e expressões de consulta.

Métodos de extensão de operadores de consulta padrão

O exemplo a seguir mostra um simples expressão de consulta e a consulta semanticamente equivalente escrito como um consulta baseada no método.

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
 */

A saída dos dois exemplos é idêntica. Você pode ver que tipo de variável de consulta é o mesmo em ambos os formulários: IEnumerable<T>.

Para compreender a consulta com base no método, vamos examiná-lo mais de perto. No lado direito da expressão, observe que o where cláusula agora é expressa como um método de instância na numbers tem o tipo de objeto, que, como você lembrará IEnumerable<int>. Se você estiver familiarizado com a classe genérica IEnumerable<T> interface, você sabe que ele não tem um Where método. No entanto, se você chamar a lista de conclusão de IntelliSense no Visual Studio IDE, você verá não só uma Where método, mas muitos outros métodos, como Select, SelectMany, Join, e Orderby. Esses são os operadores de consulta padrão.

Operadores de consulta padrão no IntelliSense

Embora parece como se IEnumerable<T> foi redefinido para incluir esses métodos adicionais, na verdade, isso não é o caso. Os operadores de consulta padrão são implementados como um novo tipo de método chamado métodos de extensão. Métodos de extensões "estendem" um tipo existente; pode ser chamados como se fossem os métodos de instância no tipo. Os operadores de consulta padrão estendem IEnumerable<T> e isto é porque você pode escrever numbers.Where(...).

Para começar a usar LINQ, tudo o que você precisa saber sobre os métodos de extensão é como colocá-los para o escopo em seu aplicativo usando o correto using diretivas. Isso é explicado Além disso, em Como: Criar um projeto LINQ. Do ponto de vista do aplicativo, um método de extensão e um método de instância regulares são os mesmos.

Para obter mais informações sobre estes métodos de extensão, consulte Métodos de extensão (guia de programação TRANSLATION FROM VPE FOR CSHARP). Para obter mais informações sobre os operadores de consulta padrão, consulte Visão geral operadores de consulta padrão. Alguns LINQ provedores, como LINQ to SQL e LINQ to XML, implementar seus próprios operadores de consulta padrão e os métodos de extensão adicionais para outros tipos, além de IEnumerable<T>.

Expressões Lambda

No exemplo anterior, observe que a expressão condicional (num % 2 == 0) é passada como um argumento na linha para o Where método: Where(num => num % 2 == 0). Essa expressão in-line é chamado de uma expressão lambda. É uma maneira conveniente de escrever código que teria que ser escrito no formulário mais complicado, como um método anônimo, um delegado genérico ou uma árvore de expressão. Em C# => é o operador lambda, que é lido como "vai para". O num à esquerda do operador é a variável de entrada que corresponde à num na expressão de consulta. O compilador pode inferir o tipo de num porque ele sabe que numbers é genérico IEnumerable<T> tipo. O corpo do lambda é da mesma forma que a expressão na sintaxe de consulta ou em outros C# a expressão ou instrução; Ele pode incluir chamadas de método e outra lógica complexa. O "return value" é apenas o resultado da expressão.

Para começar a usar LINQ, você não precisará usar lambdas extensivamente. Entretanto, determinadas consultas só podem ser expresso na sintaxe do método e algumas delas requerem expressões lambda. Depois de familiarizar mais com lambdas, você encontrará o que eles são uma ferramenta poderosa e flexível no seu LINQ caixa de ferramentas. Para obter mais informações, consulte Expressões lambda (guia de programação TRANSLATION FROM VPE FOR CSHARP).

Composição de consultas

No exemplo de código anterior, observe que o OrderBy método é invocado usando o operador de ponto na chamada para Where. Whereproduz uma seqüência de filtrado e, em seguida, Orderby opera em dessa seqüência, classificando o proprietário. Porque as consultas retornam uma IEnumerable, você compõe-los na sintaxe do método por encadeando as chamadas de método. Este é o que o compilador faz nos bastidores, quando você escrever consultas usando a sintaxe de consulta. E como uma variável de consulta não armazenam os resultados da consulta, você pode modificá-la ou usá-lo como base para uma nova consulta a qualquer momento, mesmo depois que ele foi executado.

Consulte também

Outros recursos

Guia de Introdução do LINQ em C#