🎯 Objetivo: Neste capítulo, você irá dominar dois conceitos poderosos em C#: Delegates e Eventos. Juntos, eles permitem criar programas altamente desacoplados e baseados em eventos, onde componentes se comunicam de forma flexível, sem precisar saber a identidade uns dos outros.
Até agora, nossa comunicação entre classes foi direta: um objeto A chama um método de um objeto B. Mas e se o objeto A não souber qual método de B chamar? Ou se B nem existir ainda? Precisamos de uma forma mais flexível.
Imagine que você é o gerente de uma loja. Quando uma venda acontece, você precisa que várias pessoas sejam notificadas: o setor de relatórios, o contador e o estoque. Em vez de chamar cada um diretamente, você pode ter uma "lista de contatos" para a tarefa "notificar venda". Você só precisa se preocupar em chamar essa lista, e o sistema se encarrega de contatar a todos.
Um delegate em C# é exatamente isso: uma referência a um método. Ele é um tipo que define a assinatura de um método (tipo de retorno e parâmetros) e pode armazenar uma referência a um ou mais métodos compatíveis. Pense nele como um "ponteiro de função" seguro e gerenciado pelo .NET.
Comparação com Java: Em Java, você alcançaria uma funcionalidade similar usando Interfaces (como ActionListener) ou, em versões mais recentes, com Interfaces Funcionais e Lambdas. C# usa um tipo de primeira classe (delegate) para representar esse conceito.
Declaração do Delegate: Primeiro, você declara o tipo do delegate, definindo a assinatura dos métodos que ele poderá referenciar.
// Declara um delegate chamado NotificarVendaHandler.
// Ele pode referenciar qualquer método que retorne void e receba (string, decimal).
public delegate void NotificarVendaHandler(string produto, decimal valor);
Referenciando um Método: Depois, você cria uma instância do delegate e atribui a ela um ou mais métodos que correspondam à sua assinatura.
public class Relatorio
{
public void GerarRelatorioVenda(string produto, decimal valor)
{
Console.WriteLine($"Relatório: Venda de {produto} por R${valor} registrada.");
}
}
public class Notificador
{
public void EnviarSMS(string produto, decimal valor)
{
Console.WriteLine($"Notificação: Venda de {produto} concluída. Enviando SMS.");
}
}
Chamando o Delegate: Agora, você pode invocar o delegate, e ele irá chamar todos os métodos que foram atribuídos a ele.
public class Main
{
public static void Main(string[] args)
{
var relatorio = new Relatorio();
var notificador = new Notificador();
// Cria uma instância do delegate e adiciona os métodos.
// O operador += permite adicionar mais métodos.
NotificarVendaHandler notificadorVenda = relatorio.GerarRelatorioVenda;
notificadorVenda += notificador.EnviarSMS;
Console.WriteLine("Iniciando notificação de venda...");
// Invoca o delegate.
notificadorVenda("Notebook", 3500.00m);
// Ambas as classes (Relatorio e Notificador) serão chamadas.
// Você também pode remover um método com o operador -=
notificadorVenda -= relatorio.GerarRelatorioVenda;
}
}
Delegates são a base, mas eventos são o padrão de design que o C# oferece para usá-los com segurança. Um evento é uma variável do tipo delegate, mas com duas restrições cruciais:
+= (para adicionar um assinante) e = (para remover um assinante).Essa restrição protege o evento de ser acionado acidentalmente por código externo, garantindo que apenas a classe que "possui" o evento possa dispará-lo.