Aguiar Dev
LINQ Methods: O Guia Completo com Exemplos Práticos
Programação·24 de julho de 2026·13 min

LINQ Methods: O Guia Completo com Exemplos Práticos

Compartilhar:

LINQ (Language Integrated Query) é uma das funcionalidades mais poderosas do C#. Introduzido no .NET 3.5, ele traz para dentro da linguagem uma sintaxe expressiva para consultar, filtrar e transformar coleções de dados — seja uma lista em memória, um banco de dados, um XML ou qualquer fonte que implemente IEnumerable<T> ou IQueryable<T>.

Em vez de escrever loops foreach repetitivos com condicionais aninhadas, o LINQ permite expressar a intenção da operação de forma legível e declarativa:

// Sem LINQ
var resultado = new List<string>();
foreach (var nome in nomes)
{
    if (nome.StartsWith("A"))
        resultado.Add(nome);
}

// Com LINQ
var resultado = nomes.Where(n => n.StartsWith("A"));

Os métodos LINQ são extension methods definidos em System.Linq e se organizam em categorias bem definidas. Este artigo cobre todas elas.

Mapa mental com todos os métodos LINQ organizados por categoria


1. Filtering (Filtragem)

Métodos que retornam um subconjunto da coleção com base em uma condição.

var numeros = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Where

Filtra elementos que satisfazem um predicado.

var pares = numeros.Where(n => n % 2 == 0);
Entrada Saída
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 2, 4, 6, 8, 10

Take

Retorna os primeiros N elementos.

var primeiros3 = numeros.Take(3);
Entrada N Saída
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 3 1, 2, 3

Skip

Ignora os primeiros N elementos e retorna o restante.

var semOs3Primeiros = numeros.Skip(3);
Entrada N Saída
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 3 4, 5, 6, 7, 8, 9, 10

TakeWhile

Retorna elementos enquanto a condição for verdadeira, parando ao encontrar o primeiro que falha.

var enquantoMenorQue5 = numeros.TakeWhile(n => n < 5);
Entrada Condição Saída
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 n < 5 1, 2, 3, 4

SkipWhile

Ignora elementos enquanto a condição for verdadeira, retornando o restante a partir do primeiro que falha.

var aPartirDo5 = numeros.SkipWhile(n => n < 5);
Entrada Condição Saída
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 n < 5 5, 6, 7, 8, 9, 10

2. Projecting (Projeção)

Métodos que transformam cada elemento em outro formato.

var produtos = new List<(string Nome, double Preco)>
{
    ("Notebook", 3500.0),
    ("Mouse", 120.0),
    ("Teclado", 250.0)
};

Select

Projeta cada elemento em um novo formato.

var nomes = produtos.Select(p => p.Nome);
Entrada Saída
(Notebook, 3500), (Mouse, 120), (Teclado, 250) "Notebook", "Mouse", "Teclado"

SelectMany

Achata coleções aninhadas em uma única sequência.

var pedidos = new List<List<string>>
{
    new() { "Notebook", "Mouse" },
    new() { "Teclado", "Monitor" }
};

var todosItens = pedidos.SelectMany(p => p);
Entrada Saída
["Notebook","Mouse"], ["Teclado","Monitor"] "Notebook", "Mouse", "Teclado", "Monitor"

3. Joining (Junção)

Métodos para combinar duas coleções com base em uma chave comum.

var clientes = new List<(int Id, string Nome)>
{
    (1, "Alice"),
    (2, "Bruno"),
    (3, "Carol")
};

var pedidos = new List<(int ClienteId, string Produto)>
{
    (1, "Notebook"),
    (2, "Mouse"),
    (1, "Teclado")
};

Join

Une duas coleções por uma chave, retornando pares correspondentes (como INNER JOIN no SQL).

var resultado = clientes.Join(
    pedidos,
    c => c.Id,
    p => p.ClienteId,
    (c, p) => $"{c.Nome} comprou {p.Produto}"
);
Cliente Pedido Saída
(1, Alice), (2, Bruno), (3, Carol) (1, Notebook), (2, Mouse), (1, Teclado) "Alice comprou Notebook", "Bruno comprou Mouse", "Alice comprou Teclado"

GroupJoin

Une duas coleções por chave, retornando cada elemento da esquerda com sua coleção de correspondências (como LEFT JOIN no SQL).

var resultado = clientes.GroupJoin(
    pedidos,
    c => c.Id,
    p => p.ClienteId,
    (c, ps) => $"{c.Nome}: {string.Join(", ", ps.Select(p => p.Produto))}"
);
Saída
"Alice: Notebook, Teclado"
"Bruno: Mouse"
"Carol: "

Zip

Combina duas sequências elemento a elemento, como um zíper.

var letras = new List<string> { "A", "B", "C" };
var numeros = new List<int> { 1, 2, 3 };

var combinados = letras.Zip(numeros, (l, n) => $"{l}{n}");
Entrada 1 Entrada 2 Saída
"A", "B", "C" 1, 2, 3 "A1", "B2", "C3"

4. Ordering (Ordenação)

Métodos para ordenar elementos.

var pessoas = new List<(string Nome, int Idade)>
{
    ("Carlos", 30),
    ("Ana", 25),
    ("Bruno", 30),
    ("Diana", 25)
};

OrderBy / OrderByDescending

Ordena a coleção por uma chave, em ordem crescente ou decrescente.

var porIdade = pessoas.OrderBy(p => p.Idade);
var porIdadeDesc = pessoas.OrderByDescending(p => p.Idade);
Entrada OrderBy(Idade) OrderByDescending(Idade)
Carlos(30), Ana(25), Bruno(30), Diana(25) Ana(25), Diana(25), Carlos(30), Bruno(30) Carlos(30), Bruno(30), Ana(25), Diana(25)

ThenBy / ThenByDescending

Critério de ordenação secundário, aplicado após OrderBy.

var ordenado = pessoas
    .OrderBy(p => p.Idade)
    .ThenBy(p => p.Nome);
Saída
Ana(25), Diana(25), Bruno(30), Carlos(30)

Reverse

Inverte a ordem atual da sequência.

var numeros = new List<int> { 1, 2, 3, 4, 5 };
var invertido = numeros.Reverse();
Entrada Saída
1, 2, 3, 4, 5 5, 4, 3, 2, 1

5. Grouping (Agrupamento)

GroupBy

Agrupa elementos por uma chave, retornando coleções nomeadas.

var funcionarios = new List<(string Nome, string Depto)>
{
    ("Alice", "TI"),
    ("Bruno", "RH"),
    ("Carol", "TI"),
    ("Diego", "RH"),
    ("Eva", "TI")
};

var grupos = funcionarios.GroupBy(f => f.Depto);

foreach (var grupo in grupos)
    Console.WriteLine($"{grupo.Key}: {string.Join(", ", grupo.Select(f => f.Nome))}");
Entrada Saída
Alice(TI), Bruno(RH), Carol(TI), Diego(RH), Eva(TI) TI → Alice, Carol, Eva / RH → Bruno, Diego

6. Conversion (Conversão)

Métodos para converter a sequência para outro tipo de coleção.

IEnumerable<string> nomes = new[] { "Ana", "Bruno", "Carol" };

ToArray

Converte para array T[].

string[] array = nomes.ToArray();

ToList

Converte para List<T>.

List<string> lista = nomes.ToList();

ToDictionary

Converte para Dictionary<TKey, TValue>.

var produtos = new List<(int Id, string Nome)>
{
    (1, "Notebook"), (2, "Mouse"), (3, "Teclado")
};

Dictionary<int, string> dict = produtos.ToDictionary(p => p.Id, p => p.Nome);
Entrada Saída
(1,Notebook), (2,Mouse), (3,Teclado) {1:"Notebook", 2:"Mouse", 3:"Teclado"}

ToLookup

Como ToDictionary, mas permite múltiplos valores por chave (ILookup<TKey, TElement>).

var vendas = new List<(string Vendedor, string Produto)>
{
    ("Alice", "Notebook"),
    ("Bruno", "Mouse"),
    ("Alice", "Teclado")
};

ILookup<string, string> lookup = vendas.ToLookup(v => v.Vendedor, v => v.Produto);

// lookup["Alice"] → ["Notebook", "Teclado"]

AsEnumerable

Força a avaliação como IEnumerable<T> — útil para sair do contexto IQueryable (Entity Framework) e executar o restante da query em memória.

var resultado = dbContext.Produtos
    .Where(p => p.Ativo)
    .AsEnumerable()
    .Where(p => MinhaFuncaoLocal(p));

AsQueryable

Converte IEnumerable<T> para IQueryable<T>, permitindo composição de queries com Expression Trees.

IQueryable<string> query = nomes.AsQueryable().Where(n => n.Length > 3);

Cast

Faz cast de todos os elementos para o tipo especificado. Lança exceção se algum elemento não for compatível.

var objetos = new ArrayList { "Ana", "Bruno", "Carol" };
IEnumerable<string> strings = objetos.Cast<string>();

OfType

Filtra e faz cast apenas dos elementos do tipo especificado, ignorando os demais.

var misturado = new ArrayList { "Ana", 42, "Bruno", 3.14, "Carol" };
IEnumerable<string> somenteStrings = misturado.OfType<string>();
Entrada Saída
"Ana", 42, "Bruno", 3.14, "Carol" "Ana", "Bruno", "Carol"

7. Set (Conjuntos)

Operações entre coleções inspiradas na teoria dos conjuntos.

var a = new List<int> { 1, 2, 3, 4, 5 };
var b = new List<int> { 3, 4, 5, 6, 7 };

Concat

Concatena duas sequências (mantém duplicatas).

var resultado = a.Concat(b);
A B Saída
1,2,3,4,5 3,4,5,6,7 1,2,3,4,5,3,4,5,6,7

Union

Une duas sequências eliminando duplicatas.

var resultado = a.Union(b);
A B Saída
1,2,3,4,5 3,4,5,6,7 1,2,3,4,5,6,7

Except

Retorna elementos de A que não estão em B (diferença).

var resultado = a.Except(b);
A B Saída
1,2,3,4,5 3,4,5,6,7 1,2

Intersect

Retorna apenas os elementos presentes em ambas as coleções.

var resultado = a.Intersect(b);
A B Saída
1,2,3,4,5 3,4,5,6,7 3,4,5

8. Element (Elementos Individuais)

Métodos para obter um único elemento da coleção.

var numeros = new List<int> { 10, 20, 30, 40, 50 };

First / FirstOrDefault

Retorna o primeiro elemento (ou o primeiro que satisfaz um predicado). First lança exceção se vazio; FirstOrDefault retorna o valor padrão do tipo.

var primeiro = numeros.First();                    // 10
var primeiroPar = numeros.First(n => n > 25);      // 30
var nenhum = numeros.FirstOrDefault(n => n > 100); // 0

Last / LastOrDefault

Retorna o último elemento (ou o último que satisfaz um predicado).

var ultimo = numeros.Last();                   // 50
var ultimoAbaixo40 = numeros.Last(n => n < 40); // 30

Single / SingleOrDefault

Retorna exatamente um elemento. Lança exceção se houver zero ou mais de um resultado. Útil quando você quer garantir unicidade.

var unico = numeros.Single(n => n == 30);          // 30
var nulo = numeros.SingleOrDefault(n => n == 99);  // 0

ElementAt / ElementAtOrDefault

Retorna o elemento em um índice específico.

var terceiro = numeros.ElementAt(2);              // 30
var foraDoRange = numeros.ElementAtOrDefault(10); // 0
Índice Entrada Saída
2 10, 20, 30, 40, 50 30
10 10, 20, 30, 40, 50 0 (padrão)

9. Aggregation (Agregação)

Métodos que reduzem uma coleção a um único valor.

var salarios = new List<double> { 3500, 5200, 4800, 6100, 2900 };

Count

Conta o número de elementos (opcionalmente com filtro).

var total = salarios.Count();                    // 5
var acimaDe4000 = salarios.Count(s => s > 4000); // 3

Sum

Soma todos os valores.

var totalSalarios = salarios.Sum(); // 22500

Average

Calcula a média.

var media = salarios.Average(); // 4500

Min / Max

Retorna o menor ou maior valor.

var menor = salarios.Min(); // 2900
var maior = salarios.Max(); // 6100
Método Entrada Saída
Count() 3500,5200,4800,6100,2900 5
Sum() 3500,5200,4800,6100,2900 22500
Average() 3500,5200,4800,6100,2900 4500
Min() 3500,5200,4800,6100,2900 2900
Max() 3500,5200,4800,6100,2900 6100

Aggregate

Aplica uma função acumuladora elemento a elemento — o método mais flexível de todos.

var numeros = new List<int> { 1, 2, 3, 4, 5 };

// Calcula o fatorial: 1 * 2 * 3 * 4 * 5
var fatorial = numeros.Aggregate((acumulador, atual) => acumulador * atual);
// Resultado: 120

// Com valor semente e transformação final
var resultado = numeros.Aggregate(
    seed: 100,
    func: (acc, n) => acc + n,
    resultSelector: total => $"Soma com semente: {total}"
);
// Resultado: "Soma com semente: 115"
Entrada Operação Saída
1,2,3,4,5 acc * atual 120

10. Quantifiers (Quantificadores)

Métodos que retornam bool sobre uma condição na coleção.

var notas = new List<int> { 7, 8, 5, 9, 6 };

Any

Retorna true se algum elemento satisfaz a condição (ou se a coleção não está vazia).

var temReprovado = notas.Any(n => n < 6); // false
var temElementos = notas.Any();            // true

All

Retorna true se todos os elementos satisfazem a condição.

var todosAprovados = notas.All(n => n >= 5); // true
var todosAcimaDe8 = notas.All(n => n > 8);  // false

Contains

Retorna true se a coleção contém o elemento especificado.

var temNota9 = notas.Contains(9);  // true
var temNota10 = notas.Contains(10); // false

SequenceEqual

Retorna true se duas sequências possuem os mesmos elementos na mesma ordem.

var lista1 = new List<int> { 1, 2, 3 };
var lista2 = new List<int> { 1, 2, 3 };
var lista3 = new List<int> { 3, 2, 1 };

lista1.SequenceEqual(lista2); // true
lista1.SequenceEqual(lista3); // false
Sequência A Sequência B Saída
1, 2, 3 1, 2, 3 true
1, 2, 3 3, 2, 1 false

11. Generation (Geração)

Métodos estáticos que criam sequências sem precisar de uma coleção de entrada.

Range

Gera uma sequência de inteiros consecutivos.

var de1a10 = Enumerable.Range(1, 10);
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Start Count Saída
1 10 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
5 5 5, 6, 7, 8, 9

Repeat

Gera uma sequência com o mesmo valor repetido N vezes.

var zeros = Enumerable.Repeat(0, 5);
// 0, 0, 0, 0, 0

var defaults = Enumerable.Repeat("N/A", 3);
// "N/A", "N/A", "N/A"
Element Count Saída
0 5 0, 0, 0, 0, 0
"N/A" 3 "N/A", "N/A", "N/A"

Empty

Retorna uma sequência vazia do tipo especificado. Útil para evitar null e como valor neutro em composições.

IEnumerable<string> vazia = Enumerable.Empty<string>();

// Útil em combinações:
var resultado = fonte ?? Enumerable.Empty<string>();

Conclusão

O LINQ é uma das features que mais diferencia o C# de outras linguagens. Dominar seus métodos significa escrever código mais expressivo, conciso e seguro — e evitar aquelas classes de util com loops manuais que todo projeto acumula com o tempo.

Um bom ponto de partida é se familiarizar primeiro com Where, Select, OrderBy, GroupBy e as agregações básicas. Os métodos de Join, SelectMany, Aggregate e Generation vêm naturalmente com a prática.

Dica: O LINQ usa execução adiada (deferred execution) — a query só é executada quando você itera sobre o resultado (com foreach, ToList(), ToArray(), etc.). Isso é importante para performance e para evitar comportamentos inesperados.

Compartilhar: