Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Escolha uma expressão lambda quando quiser passar uma operação curta para outro método e a operação é mais clara ao lado da chamada que a utiliza. Uma regra inline mostra aos leitores como seleciona ou transforma itens; um método nomeado permite-lhes seguir o propósito da operação antes de inspecionarem os seus detalhes.
Tip
Este artigo ensina escolhas práticas para programadores que conhecem métodos e coleções em C#. Para a sintaxe e regras lambda completas, veja a referência de expressões lambda.
Uma expressão lambda é uma função sem nome que escreves onde outro pedaço de código precisa de comportamento.
A seguinte lambda aceita uma sessão e devolve se a sessão tem lugares disponíveis:
session => session.Registered < session.Capacity
O operador => separa os parâmetros à esquerda do corpo à direita. Leia-se como "vai para".
Transmitir o comportamento para um método
Muitas APIs .NET aceitam um delegate, que é um tipo que representa o comportamento com uma lista de parâmetros específica e um tipo de retorno. Um lambda fornece esse comportamento. Para uma introdução aos tipos de delegados como Func e Action, consulte Expressões lambda, delegados e eventos.
O exemplo seguinte funciona com sessões de workshop. A sessão WorkshopSession contém um título, duração, capacidade e número de registos.
int maximumMinutes = 60;
var shortSessions = sessions
.Where(session => session.DurationMinutes <= maximumMinutes)
.OrderBy(session => session.Title);
foreach (WorkshopSession session in shortSessions)
{
Console.WriteLine(session.Title);
}
A primeira lambda indica Where quais as sessões a manter. O segundo indica a OrderBy por que valor deve ser ordenado. Os métodos recebem comportamento sem conhecer os detalhes de qualquer uma das duas regras.
Escolha um formulário de parâmetro
Escolha a forma de parâmetro mais curta que permaneça clara:
session => session.DurationMinutes <= 60
Para um parâmetro, omita os parênteses quando o compilador pode inferir o tipo. Utilize parênteses vazios sem parâmetros:
() => DateTime.Now
Utilize parênteses para dois ou mais parâmetros:
(left, right) => left + right
Normalmente, o método que recebe a lambda fornece informação suficiente para que o compilador possa inferir os tipos de parâmetros. Escreva tipos explícitos quando a inferência precisar de ajuda ou quando os tipos melhoram a clareza:
(WorkshopSession session) => session.Title
A referência das expressões lambda abrange modificadores de parâmetros, atributos, valores padrão e outras formas especializadas.
Escolha uma expressão ou o corpo de uma instrução
Use uma lambda de expressão quando uma expressão calcula o resultado:
session => session.Registered < session.Capacity
Use uma lambda de instruções quando a operação precisa de mais do que uma instrução. Envolva o corpo em chavetas e inclua return quando o lambda devolver um valor:
var descriptions = sessions.Select(session =>
{
int seatsLeft = session.Capacity - session.Registered;
string availability = seatsLeft > 0 ? $"{seatsLeft} seats left" : "full";
return $"{session.Title}: {availability}";
});
Console.WriteLine(string.Join(Environment.NewLine, descriptions));
Mantenha as lambdas de instrução breves. Quando o corpo precisa de vários passos ou a mesma lógica aparece mais do que uma vez, dê ao comportamento um nome descritivo com uma função local ou método regular.
Capturar valores do âmbito envolvente
Um lambda pode usar uma variável declarada no método circundante. Esta utilização chama-se captura. No primeiro exemplo, a lambda de seleção captura maximumMinutes:
int maximumMinutes = 60;
var shortSessions = sessions.Where(
session => session.DurationMinutes <= maximumMinutes);
Captura ajuda uma regra curta a usar contexto local. O lambda captura a variável em si, não uma cópia do seu valor. Se a variável mudar antes do lambda correr, o lambda vê o valor atual.
Tornar o contexto necessário fácil de identificar. Se um lambda não precisa de estado circundante, adicione static para evitar capturas acidentais e torne essa independência visível para os leitores:
var openSessions = sessions.Where(
static session => session.Registered < session.Capacity);
Um lambda estático pode usar os seus parâmetros, valores que declara, constantes e membros estáticos. Não pode usar variáveis locais ou o estado de instância do código circundante.
Escolha um lambda, grupo de métodos ou função local
Várias formas C# podem fornecer comportamento a um parâmetro de delegado:
- Use uma expressão lambda para comportamento curto que se leia claramente ao lado da chamada.
- Use um grupo de métodos quando um método existente tem a assinatura necessária e o seu nome explica o comportamento.
- Use uma função local quando o elemento que contém precisar de lógica nomeada reutilizável, recursão ou um corpo demasiado grande para um lambda inline.
- Utilize um método regular quando vários membros precisarem desse comportamento.
Um method group é um nome de método sem a sua lista de argumentos. O compilador converte o método de correspondência para o tipo de delegado requerido:
var openSessions = sessions.Where(HasOpenSeats);
foreach (WorkshopSession session in openSessions)
{
Console.WriteLine($"Open: {session.Title}");
}
static bool HasOpenSeats(WorkshopSession session) =>
session.Registered < session.Capacity;
Where(HasOpenSeats) comunica a mesma regra que Where(session => HasOpenSeats(session)) com menos código. O nome do método indica aos leitores o que a regra testa; uma comparação inline mostra como testa essa regra. Mantenha o wrapper lambda quando adicionar um argumento, combinar operações ou tornar a chamada mais clara.
Para uma comparação local detalhada, veja Funções Locais.