Partilhar via


Recursos do C# que suportam LINQ

Expressões de consulta

As expressões de consulta usam uma sintaxe declarativa semelhante a SQL ou XQuery para consultar coleções System.Collections.Generic.IEnumerable<T> . Em tempo de compilação, a sintaxe de consulta é convertida em chamadas de método para a implementação dos métodos de consulta padrão por um provedor LINQ. Os aplicativos controlam os operadores de consulta padrão que estão no escopo especificando o namespace apropriado com uma using diretiva. A expressão de consulta a seguir usa uma matriz de cadeias de caracteres, agrupa-as de acordo com o primeiro caractere da cadeia de caracteres e ordena os grupos.

var query = from str in stringArray
            group str by str[0] into stringGroup
            orderby stringGroup.Key
            select stringGroup;

Variáveis digitadas implicitamente (var)

Você pode usar o modificador var para instruir o compilador a inferir e atribuir o tipo, conforme mostrado aqui:

var number = 5;
var name = "Virginia";
var query = from str in stringArray
            where str[0] == 'm'
            select str;

Variáveis declaradas como var fortemente tipadas, assim como variáveis cujo tipo você especifica explicitamente. O uso de var torna possível criar tipos anônimos, mas apenas para variáveis locais. Para obter mais informações, consulte Variáveis locais digitadas implicitamente.

Inicializadores de objeto e coleção

Os inicializadores de objeto e coleção tornam possível inicializar objetos sem chamar explicitamente um construtor para o objeto. Os inicializadores geralmente são usados em expressões de consulta quando projetam os dados de origem em um novo tipo de dados. Supondo uma classe nomeada Customer com public Name e Phone propriedades, o inicializador de objeto pode ser usado como no código a seguir:

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

Continuando com sua Customer classe, suponha que há uma fonte de dados chamada IncomingOrders, e que, para cada ordem com um grande OrderSize, você gostaria de criar uma nova Customer com base nessa ordem. Uma consulta LINQ pode ser executada nesta fonte de dados e usar a inicialização do objeto para preencher uma coleção:

var newLargeOrderCustomers = from o in IncomingOrders
                            where o.OrderSize > 5
                            select new Customer { Name = o.Name, Phone = o.Phone };

A fonte de dados pode ter mais propriedades definidas do que a Customer classe, como OrderSize, mas com a inicialização do objeto, os dados retornados da consulta são moldados no tipo de dados desejado, você escolhe os dados que são relevantes para sua classe. Como resultado, agora você tem um System.Collections.Generic.IEnumerable<T> preenchido com os novos Customers que você queria. O exemplo anterior também pode ser escrito na sintaxe do método LINQ:

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });

A partir do C# 12, você pode usar uma expressão de coleção para inicializar uma coleção.

Para obter mais informações, consulte:

Tipos Anônimos

O compilador constrói um tipo anônimo. O nome do tipo só está disponível para o compilador. Os tipos anônimos fornecem uma maneira conveniente de agrupar um conjunto de propriedades temporariamente em um resultado de consulta sem precisar definir um tipo nomeado separado. Os tipos anônimos são inicializados com uma nova expressão e um inicializador de objeto, conforme mostrado aqui:

select new {name = cust.Name, phone = cust.Phone};

A partir do C# 7, você pode usar tuplas para criar tipos sem nome.

Métodos da Extensão

Um método de extensão é um método estático que pode ser associado a um tipo, para que ele possa ser chamado como se fosse um método de instância no tipo. Esse recurso permite que você "adicione" novos métodos aos tipos existentes sem realmente modificá-los. Os operadores de consulta padrão são um conjunto de métodos de extensão que fornecem funcionalidade de consulta LINQ para qualquer tipo que implemente IEnumerable<T>o .

Expressões do Lambda

Uma expressão lambda é uma função embutida que usa o operador para separar parâmetros => de entrada do corpo da função e pode ser convertida em tempo de compilação para um delegado ou uma árvore de expressão. Na programação LINQ, você encontra expressões lambda quando faz chamadas diretas de método para os operadores de consulta padrão.

Expressões como dados

Os objetos de consulta são compostáveis, o que significa que você pode retornar uma consulta de um método. Os objetos que representam consultas não armazenam a coleção resultante, mas sim as etapas para produzir os resultados quando necessário. A vantagem de retornar objetos de consulta de métodos é que eles podem ser compostos ou modificados. Portanto, qualquer valor de retorno ou out parâmetro de um método que retorna uma consulta também deve ter esse tipo. Se um método materializa uma consulta em um concreto List<T> ou Array tipo, ele retorna os resultados da consulta em vez da própria consulta. Uma variável de consulta que é retornada de um método ainda pode ser composta ou modificada.

No exemplo a seguir, o primeiro método QueryMethod1 retorna uma consulta como um valor de retorno e o segundo método QueryMethod2 retorna uma consulta como um out parâmetro (returnQ no exemplo). Em ambos os casos, é uma consulta que é retornada, não os resultados da consulta.

IEnumerable<string> QueryMethod1(int[] ints) =>
    from i in ints
    where i > 4
    select i.ToString();

void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
    returnQ =
        from i in ints
        where i < 4
        select i.ToString();

int[] nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var myQuery1 = QueryMethod1(nums);

A consulta myQuery1 é executada no seguinte loop foreach.

foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}

Coloque o ponteiro do rato sobre myQuery1 ele para ver o seu tipo.

Você também pode executar a consulta retornada diretamente QueryMethod1 , sem usar myQuery1o .

foreach (var s in QueryMethod1(nums))
{
    Console.WriteLine(s);
}

Coloque o ponteiro do mouse sobre a chamada para ver seu tipo de QueryMethod1 retorno.

QueryMethod2 Retorna uma consulta como o valor de seu out parâmetro:

QueryMethod2(nums, out IEnumerable<string> myQuery2);

// Execute the returned query.
foreach (var s in myQuery2)
{
    Console.WriteLine(s);
}

Você pode modificar uma consulta usando a composição da consulta. Nesse caso, o objeto de consulta anterior é usado para criar um novo objeto de consulta. Esse novo objeto retorna resultados diferentes do objeto de consulta original.

myQuery1 =
    from item in myQuery1
    orderby item descending
    select item;

// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}