Introdução aos eventos
Os eventos são, tal como os delegados, um mecanismo de vinculação 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.
Provavelmente já utilizou eventos em alguma 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 certamente 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. Estes dois componentes podem não ser escritos pela mesma organização, e podem até ser atualizados em horários totalmente diferentes.
Deve ser muito simples inscrever-se num 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 ter nenhum assinante de evento anexado.
Você pode ver que as metas para eventos são muito 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 assinar ou cancelar a assinatura de eventos é uma extensão da sintaxe para delegados.
Para definir um evento, use a event
palavra-chave:
public event EventHandler<FileListArgs> Progress;
O tipo de evento (EventHandler<FileListArgs>
neste exemplo) deve ser um tipo delegado. Há uma série de 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 relatar 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 Closing
evento pode incluir um argumento que indicaria se a operação de fechamento deve continuar ou não. Outros cenários podem permitir 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:
Progress?.Invoke(this, new FileListArgs(file));
Conforme discutido na seção sobre delegados, o ?. O operador facilita a garantia de que você não tenta aumentar o evento quando não há assinantes para esse evento.
Você se inscreve em um evento usando o +=
operador:
EventHandler<FileListArgs> onProgress = (sender, eventArgs) =>
Console.WriteLine(eventArgs.FoundFile);
fileLister.Progress += onProgress;
O método manipulador normalmente tem o prefixo 'On' seguido pelo nome do evento, como mostrado acima.
Você cancela a inscrição usando o -=
operador:
fileLister.Progress -= onProgress;
É 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.