Compartilhar via


Introdução a eventos

Anterior

Eventos são, assim como delegados, um mecanismo de associação tardia. Na verdade, os eventos são criados com base no suporte de idioma para delegados.

Os eventos são uma maneira de um objeto difundir (para todos os componentes interessados no sistema) que algo aconteceu. Qualquer outro componente pode assinar o evento e ser notificado quando um evento é gerado.

Você provavelmente usou eventos em algumas de suas codificações. Muitos sistemas gráficos têm um modelo de evento para relatar a interação do usuário. Esses eventos relatariam movimento do mouse, pressionamentos de botão e interações semelhantes. Esse é um dos cenários mais comuns, mas não o único cenário em que eventos são usados.

Você pode definir eventos que devem ser gerados para suas classes. 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.

Assinar um evento também cria um acoplamento entre dois objetos (a origem do evento e o coletor do evento). Você precisa garantir que o coletor do evento cancele a assinatura da origem do evento quando não houver mais interesse nos eventos.

Metas de design para suporte a eventos

O design de linguagem para eventos tem como destino estas metas:

  • Habilitar um acoplamento mínimo entre uma origem do evento 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 assinar um evento e cancelar a assinatura desse mesmo evento.
  • As origens do evento devem dar suporte a vários assinantes de eventos. Elas também devem dar suporte a não ter assinantes de evento anexados.

Você pode ver que as metas para eventos são semelhantes às metas dos delegados. É por isso que o suporte à linguagem de eventos é baseado no suporte à linguagem delegada.

Suporte à linguagem para eventos

A sintaxe para definir eventos e assinar ou cancelar a inscrição de eventos é uma extensão da sintaxe para delegados.

Use a event palavra-chave para definir um evento:

public event EventHandler<FileFoundArgs>? FileFound;

O tipo do evento (EventHandler<FileListArgs> neste exemplo) deve ser um tipo delegado. Há convenções que você deve seguir ao declarar um evento. Normalmente, o tipo de delegado do evento tem um retorno nulo. As declarações de evento devem ser um verbo ou uma locução verbal. Use o passado ao relatar eventos já ocorridos. Use um verbo tenso atual (por exemplo) Closingpara relatar algo que está prestes a acontecer. Muitas vezes, usar o tempo presente indica que sua classe dá suporte a algum tipo de comportamento de personalização. Um dos cenários mais comuns é dar suporte ao cancelamento. Por exemplo, um Closing evento pode incluir um argumento que indica 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 do 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 você quiser acionar o evento, chame os manipuladores de eventos usando a sintaxe de invocação delegada:

FileFound?.Invoke(this, new FileFoundArgs(file));

Conforme discutido na seção sobre delegados, o operador ?. facilita a garantia de que você não tente acionar o evento quando não houver assinantes desse evento.

Você assina 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 de manipulador normalmente tem o prefixo 'On' seguido pelo nome do evento, conforme mostrado no código anterior.

Você cancela a assinatura 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 da assinatura remova o manipulador. Se, em vez disso, você tiver usado o corpo da expressão lambda, você estará 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 evento típicos e variações diferentes neste exemplo.

Próximo