CodeGym /Cursos /C# SELF /Sintaxe de expressões lambda (

Sintaxe de expressões lambda ( =>)

C# SELF
Nível 49, Lição 1
Disponível

1. Introdução

Você talvez não soubesse, mas uma das perguntas favoritas em entrevistas é — “O que você sabe sobre expressões lambda?”. Por que perguntam isso? Porque é uma coisa muito prática e "na moda" em C#, que deixa o código menor e mais expressivo. Se métodos anônimos são como escrever uma carta à mão, as expressões lambda são como mandar uma mensagem no mensageiro: rápido, compacto e às vezes até com emojis (bom, quase).

As expressões lambda chegaram no C# na versão 3.0 e desde então se espalharam por todo lado: em LINQ, handlers de eventos, threads, coleções e até em bibliotecas de IA no .NET.

Expressão lambda — é uma forma de declarar um método diretamente no ponto do código, "in-loco", sem nome, supercurta e clara. A sintaxe principal sempre fica assim:

(parâmetros) => expressão_ou_bloco_de_código

Esse "chevron" => é chamado de “operador lambda” ou “seta”.

Uma pequena analogia

Lembre-se de como você escreve uma receita: “Pegar a maçã, cortar ela, colocar na tigela”.
Em C# isso seria:

(maçã) => cortar(maçã)

2. Transformando um método anônimo em lambda

Suponha que temos um delegate:

delegate int SquareDelegate(int x);

Um método anônimo ficaria assim:

SquareDelegate sq = delegate(int x) {
    return x * x;
};

E agora a mesma coisa com expressão lambda:

SquareDelegate sq = (int x) => { return x * x; };

Mas o C# consegue inferir os tipos, e podemos encurtar ainda mais:

SquareDelegate sq = x => x * x;

Impressionante compactação!

Comparação com método "comum" e função anônima

Maneira Declaração Onde pode ser usado Contras
Método nomeado Na classe Em qualquer lugar Precisa de nome, mais código
Método anônimo No código Apenas com delegates Sintaxe mais verbosa
Expressão lambda No código Em qualquer lugar com delegates Às vezes o tipo não é óbvio

3. Sintaxe de expressão lambda: variações

Parâmetros

Sem parâmetros:

Action hello = () => Console.WriteLine("Olá, mundo!");

Um parâmetro (pode omitir parênteses):

Func<int, int> inc = x => x + 1;

Vários parâmetros (precisa parênteses):

Func<int, int, int> sum = (a, b) => a + b;

Corpo da lambda

Uma expressão — sem chaves e sem return:

x => x * x

Bloco de código — chaves, é preciso return:

(x, y) =>
{
    int z = x + y;
    return z * z;
}

Tipos dos parâmetros

Na maioria das vezes não precisa especificar o tipo — o compilador infere. Mas se quiser, pode:

(x, y) => x + y      // O compilador infere os tipos.
(int x, int y) => x + y  // Pode declarar explicitamente.

4. Nuances e exemplos mais reais

Uso com coleções

Lembre do nosso miniprojeto didático (por exemplo, lista de usuários)? Suponha que temos um array de números:

int[] numbers = { 1, 2, 3, 4, 5 };

Precisamos selecionar apenas os números pares:

var evenNumbers = numbers.Where(n => n % 2 == 0);

Aqui Where é um método de extensão do LINQ, e a condição é nosso filtro lambda.

Passando para um método

Suponha que temos um método-delegate:

public delegate bool Filter(int number);

public static int[] FilterNumbers(int[] data, Filter predicate)
{
    var result = new List<int>();
    foreach (var n in data)
        if (predicate(n))
            result.Add(n);
    return result.ToArray();
}

Agora passamos uma expressão lambda:

int[] evens = FilterNumbers(numbers, n => n % 2 == 0);

Lambda como handler de evento

button.Click += (sender, args) => Console.WriteLine("Botão pressionado!");

5. Lambdas e delegados genéricos padrão

É difícil imaginar lambdas sem Func<>, Action<> e Predicate<>. São tipos especiais de delegates:

  • Action — não retorna nada.
  • Func — retorna um valor.
  • Predicate — retorna bool, normalmente para filtragem.

Exemplo com Action:

Action<string> log = message => Console.WriteLine(message);

log("Esta mensagem via lambda!");

Exemplo com Func:

Func<int, int, int> multiply = (a, b) => a * b;
int product = multiply(3, 5); // 15

Exemplo com Predicate:

Predicate<int> isNegative = n => n < 0;

bool test = isNegative(-7); // true

6. Lambdas com múltiplas expressões: quando usar bloco

Se a lambda precisa fazer várias operações, use chaves e o return explícito:

Func<int, int, string> describeSum = (a, b) =>
{
    int sum = a + b;
    return $"Soma: {sum}";
};

Sem return o compilador vai reclamar (mas nem sempre explica bem o motivo — geralmente diz apenas que "nem todos os caminhos retornam um valor").

7. Retorno void: Action

Quando a lambda não retorna nada, use Action:

Action greet = () => Console.WriteLine("Sorria — o código compila!");

Uma lambda pode conter quantas instruções quiser:

Action<int> printSquare = x =>
{
    int sq = x * x;
    Console.WriteLine($"O quadrado de {x} é {sq}");
};

8. Restrições e erros típicos

Às vezes dá vontade de escrever a lambda bem solta, mas o compilador nem sempre concorda.

Não dá para declarar uma variável com o mesmo nome de uma que foi capturada de fora.

Fique atento aos tipos: se a assinatura do delegate e da lambda não baterem — erro na certa.

O retorno é obrigatório se o delegate exige um valor de retorno.

Em lambdas complexas não esqueça das chaves. Uma expressão — sem chaves e sem return. Vários statements — chaves e return.

2
Tarefa
C# SELF, nível 49, lição 1
Bloqueado
Expressão lambda com múltiplos parâmetros para somar números
Expressão lambda com múltiplos parâmetros para somar números
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION