C# - Publicando e Subscrevendo Eventos


Hoje veremos como podemos publicar e subscrever eventos na linguagem C#.

Saber trabalhar com delegates e eventos é ter acesso aos blocos fundamentais sobre os quais a camada GUI opera, sendo uma forma de dissociar várias partes do seu código.

Todos os eventos na linguagem C# estão baseados em delegates, e, geralmente publicamos eventos quando queremos notificar aos componentes externos que nossa classe mudou.

Para ilustrar vamos supor que desejamos gerar um evento em uma classe Calcular, onde temos um método Soma que soma dois números, quando a soma de dois números for um múltiplo de cinco.

Para isso podemos definir um evento com base em delegate. Este evento será usado para gerar uma notificação para executar manipuladores de eventos atribuídos a ele.

Antes de ir para a parte prática temos a seguir algumas regras básicas sobre eventos:

Criando um projeto Console .Net Core

No Visual Studio 2019 Community crie um projeto do tipo Console para .NET Core chamado CShp_Events1:

No projeto console vamos criar a classe Calcular e o método Soma :

public class Calcular
{
        public double Soma(double x, double y)
        {
            double resultado = x + y;
            return resultado;
        }
    }
}

Vamos agora criar o evento que vamos chamar OnSomaIgualMultiplodeCinco na classe Calcular e associá-lo ao delegate delegateEventRaiser, e a seguir, vamos definir a condição para chamar o delegate:   

Esse código somente gera o evento OnSomaIgualMultiplodeCinco se houver algum código inscrito nele. Vamos agora remover o delegado simples, inscrevendo-o no evento, e, definindo o tratamento do evento:

Executando o projeto iremos obter o seguinte resultado:

Esse código cria uma nova instância do delegate delegateEventRaiser que aponta para o novo método chamado m_SomaIgualMultiplodeCinco. O operador +=  é usado para proteger outros métodos que já podem ter se inscrito no evento.

A Microsoft facilitou a assinatura de eventos em C# e a linha de código usada pode ser simplificada para:

calcula.OnSomaIgualMultiplodeCinco += m_SomaIgualMultiplodeCinco;

Esse código funciona bem, mas o código na classe Calcular é mais complexo do que precisa ser. A Microsoft incluiu dois  delegates principais que podemos usar ao definir eventos. Esses delegates são usados em todos os lugares do framework e podem ser mais fáceis de usar devido ao seu padrão consistente.

A seguite temos os dois delegates internos:

  1. public delegate void EventHandler(object sender, EventArgs e);
     
  2. public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

O primeiro delegate é usado simplesmente para enviar uma notificação, um evento que significa que algo aconteceu.

O segundo delegate permite retornar um ou mais valores ao método do manipulador de eventos. Requer que você crie uma instância de uma classe que deriva da classe EventArgs.

Para modificar nosso código para usar o primeiro delegate interno, podemos excluir nosso delegate e alterar nosso evento C# para usar o delegate EventHandler.

Quando disparamos o evento, devemos seguir a definição do delegate e passar os valores de parâmetro necessários.

Observe como passamos nossa instância atual de Calcular (this) para o primeiro parâmetro (sender) e, como não estamos devolvendo nenhum argumento de evento, usamos EventArgs.Empty para "e".

Usando o delegate interno EventHandler nosso código ficou mais simples.

Agora precisamos alterar a assinatura do tratamento de evento conforme o código abaixo:

Agora veremos como usar o segundo delegate interno passando o total de volta ao método manipulador de eventos.

Primeiro precisamos definir uma classe personalizada chamada MultiploDeCincoEventArgs para retornar um valor personalizado, como Total. Esta classe deve herdar da classe EventArgs.



A seguir, teremos que definir nosso evento para usar o outro delegate genérico, que inclui o tipo personalizado EventArgs : MultiploDeCincoEventArgs, e, também devemos mudar a forma como disparamos o evento criando uma instância da classe MultiploDeCincoEventArgs:

Por fim, alteramos o método do manipulador de eventos para corresponder ao delegate e receber o valor total. Aqui está o código completo:   

Assim, apresentamos conceitos básicos sobre eventos que todo o desenvolvedor C# deve conhecer.

Pegue o projeto aqui: CShp_Events1.zip

"E este evangelho do reino será pregado em todo o mundo, em testemunho a todas as nações, e então virá o fim."
Mateus 24:14

Referências:


José Carlos Macoratti