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.
Os eventos são, tal como os delegados, um mecanismo de vinculativo tardio. Na verdade, os eventos são construídos com base no suporte linguístico para delegados.
Os eventos são uma forma de um objeto transmitir (para todos os componentes interessados no sistema) que algo aconteceu. Qualquer outro componente pode se inscrever no evento e ser notificado quando um evento for gerado.
Você provavelmente usou eventos em parte da sua programação. Muitos sistemas gráficos têm um modelo de evento para relatar a interação do usuário. Esses eventos relatariam o movimento do mouse, pressionamentos de botões e interações semelhantes. Esse é um dos cenários mais comuns, mas não o único, em que os eventos são usados.
Você pode definir eventos que devem ser criados para suas aulas. Uma consideração importante ao trabalhar com eventos é que pode não haver nenhum objeto registrado para um evento específico. Você deve escrever seu código para que ele não gere eventos quando nenhum ouvinte estiver configurado.
A assinatura de um evento também cria um acoplamento entre dois objetos (a origem do evento e o coletor de eventos). Você precisa garantir que o coletor de eventos cancele a inscrição da fonte do evento quando não estiver mais interessado em eventos.
Metas de design para suporte a eventos
O design da linguagem para eventos visa estes objetivos:
- Habilite o acoplamento mínimo entre uma fonte de eventos e um coletor de eventos. Esses dois componentes podem ser escritos por organizações diferentes e podem até ser atualizados em agendas diferentes.
- Deve ser simples subscrever um evento e cancelar a subscrição desse mesmo evento.
- As fontes de eventos devem oferecer suporte a vários assinantes de eventos. Também deve suportar não haver assinantes de evento anexados.
Você pode ver que as metas para eventos são semelhantes às metas para delegados. É por isso que o suporte ao idioma do evento é baseado no suporte ao idioma delegado.
Suporte linguístico para eventos
A sintaxe para definir eventos e subscrever ou cancelar a subscrição de eventos é uma extensão da sintaxe para delegados.
Use a palavra-chave event
para definir um evento:
public event EventHandler<FileFoundArgs>? FileFound;
O tipo de evento (EventHandler<FileListArgs>
neste exemplo) deve ser um tipo delegado. Existem convenções que você deve seguir ao declarar um evento. Normalmente, o tipo de delegado de evento tem um retorno vazio. As declarações de evento devem ser um verbo ou uma frase verbal. Use o pretérito quando o evento relata algo que aconteceu. Use um verbo do tempo presente (por exemplo, Closing
) para relatar algo que está prestes a acontecer. Muitas vezes, usar o tempo presente indica que sua classe suporta algum tipo de comportamento de personalização. Um dos cenários mais comuns é suportar o cancelamento. Por exemplo, um evento Closing
pode incluir um argumento que indicaria se a operação de fechamento deve continuar ou não. Outros cenários permitem que os chamadores modifiquem o comportamento atualizando as propriedades dos argumentos de evento. Você pode gerar um evento para indicar uma próxima ação proposta que um algoritmo executará. O manipulador de eventos pode exigir uma ação diferente modificando as propriedades do argumento de evento.
Quando quiser gerar o evento, chame os manipuladores de eventos usando a sintaxe de invocação de delegado:
FileFound?.Invoke(this, new FileFoundArgs(file));
Conforme discutido na seção sobre delegados, o operador de ?.
facilita garantir que você não tente acionar o evento quando não houver assinantes para esse evento.
Você se inscreve em um evento usando o operador +=
:
var fileLister = new FileSearcher();
int filesFound = 0;
EventHandler<FileFoundArgs> onFileFound = (sender, eventArgs) =>
{
Console.WriteLine(eventArgs.FoundFile);
filesFound++;
};
fileLister.FileFound += onFileFound;
O método handler normalmente tem o prefixo 'On' seguido pelo nome do evento, conforme mostrado no código anterior.
Você cancela a inscrição usando o operador -=
:
fileLister.FileFound -= onFileFound;
É importante que você declare uma variável local para a expressão que representa o manipulador de eventos. Isso garante que o cancelamento de inscrição remova o manipulador. Se, em vez disso, você usou o corpo da expressão lambda, você está tentando remover um manipulador que nunca foi anexado, o que não faz nada.
No próximo artigo, você aprenderá mais sobre padrões de eventos típicos e diferentes variações neste exemplo.