English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
C# Orientado a Objetos (OOP)
Os eventos são notificações enviadas por objetos para representar a ocorrência de uma operação. Os eventos no .NET seguem o padrão de design Observer. A classe que dispara o evento é chamada
Publisher (publicador), a classe que recebe notificações é chamada Subscriber (assinante). Um evento pode ter múltiplos assinantes. Normalmente, o publisher dispara um evento quando uma operação ocorre. Os assinantes desejam ser notificados quando uma operação ocorre, então eles devem se registrar no evento e tratá-lo.
Em C#, os eventos são encapsulados em delegações. Dependem da delegação. A delegação define a assinatura do método do tratador de eventos da classe subscriber.
Uso de eventos com delegações publisher Classe. Outras classes que aceitam este evento são chamadas de classes subscriber(subscriber). Os eventos são declarados e gerados dentro da classe e associados a tratadores de eventos usando delegações da mesma classe ou de outras classes. A classe que contém eventos é usada para publicar eventos. Isso é chamado de Publicar-Assinar(publisher-subscriber) Modelo.
publisher- É um objeto que contém definições de eventos e delegações. A relação entre eventos e delegações também é definida neste objeto. O objeto da classe publisher chama este evento e notifica outros objetos.
Assinante(subscriber)- É um objeto que aceita eventos e fornece métodos de tratamento de eventos. A chamada de delegado no classe publisher chama o método da classe subscriber (método de tratamento de evento).
Pode-se declarar um evento em dois passos:
Declarar o delegado
Declarar uma variável de delegado usando a palavra-chave 'event'
O exemplo a seguir demonstra como declarar um evento no classe publisher.
public delegate void Notify(); // Delegado public class ProcessBusinessLogic { public event Notify ProcessCompleted; // Evento }
No exemplo acima, declaramos um delegado Notify e, em seguida, usamos a palavra-chave 'event' para declarar o evento do tipo de delegado Notify chamado ProcessCompleted no classe ProcessBusinessLogic. Portanto, a classe ProcessBusinessLogic é chamada de publisher (publicador). O delegado Notify especifica a assinatura do tratamento de eventos do evento ProcessCompleted. Ele especifica que o método do tratamento de eventos da classe subscriber (assinante) deve ter o tipo de retorno void e não ter parâmetros.
Agora, vamos ver como provocar o evento ProcessCompleted. Veja a seguinte implementação.
public delegate void Notify(); // Delegado public class ProcessBusinessLogic { public event Notify ProcessCompleted; // Evento public void StartProcess() { Console.WriteLine("Processo iniciado!"); // Alguns código aqui... OnProcessCompleted(); } protected virtual void OnProcessCompleted() //Método virtual protegido { //Se ProcessCompleted não for null, chama o delegado ProcessCompleted?.Invoke(); } }
Acima, o método StartProcess() chama o método onProcessCompleted() no final, o que provocará um evento. Normalmente, para provocar um evento, deve-se usar o nome definido no <EventName> para o método protegido e virtual. Protegido e virtual permitem que a classe derivada sobrescreva a lógica de provocação de eventos. No entanto, a classe derivada deve sempre chamar o método On<EventName> da classe base para garantir que os delegados registrados recebam o evento.
O método OnProcessCompleted() utiliza ProcessCompleted?.invoke() para chamar o delegado. Isso chamará todos os métodos de tratamento de eventos registrados no evento ProcessCompleted.
A classe assinante deve se registrar no evento ProcessCompleted e usar um método com assinatura correspondente ao delegate Notify para tratá-lo, conforme mostrado a seguir.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Registrar eventos bl.StartProcess(); } // Manipulador de eventos public static void bl_ProcessCompleted() { Console.WriteLine("Processo Concluído!"); } }
Acima, a classe Program é ProcessCompleted Os assinantes do evento. Ele usa + O operador de atribuição = para registrar eventos. Lembre-se de que isso é o mesmo que adicionarmos métodos à lista de chamadas do delegate de multicast. O método bl_processcompleted() lida com o evento porque coincide com a assinatura do delegate Notify.
.NET Framework contém tipos de delegate integrados para eventos mais comuns, EventHandler e EventHandler<TEventArgs>. Normalmente, qualquer evento deve incluir dois parâmetros: a fonte do evento e os dados do evento. Para todos os eventos que não contêm dados de evento, use o delegate EventHandler. Para eventos que contêm dados a serem enviados para o manipulador, use o delegate EventHandler<TEventArgs>.
O exemplo mostrado pode usar o delegate EventHandler, sem a necessidade de declarar um delegate Notify personalizado, conforme mostrado a seguir.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // registo de eventos bl.StartProcess(); } // manipulação de eventos public static void bl_ProcessCompleted(object sender, EventArgs e) { Console.WriteLine("Processo Concluído!"); } } public class ProcessBusinessLogic { // Use a declaração de EventHandler incorporado para eventos public event EventHandler ProcessCompleted; public void StartProcess() { Console.WriteLine("Processo iniciado!"); // Alguns código aqui... OnProcessCompleted(EventArgs.Empty); //Nenhum dado de evento } protected virtual void OnProcessCompleted(EventArgs e) { ProcessCompleted?.Invoke(this, e); } }
No exemplo acima, o método bl_ProcessCompleted() do manipulador de eventos contém dois parâmetros que correspondem ao delegate EventHandler. Ao mesmo tempo, passa this como o remetente e EventArgs. Quando usamos Invoke() para levantar o evento no método OnProcessCompleted(), ele é vazio. Porque nosso evento não precisa de qualquer dados, ele apenas notifica os assinantes de que o processo já foi concluído, então passamos EventArgs.Empty.
A maioria dos eventos envia alguns dados para os assinantes. A classe EventArgs é a classe base para todas as classes de dados de evento. O .NET contém muitos tipos de dados de evento integrados, como SerialDataReceivedEventArgs. Ele segue o padrão de nomeação de terminar todas as classes de dados de evento com EventArgs. Você pode criar classes personalizadas de dados de evento derivando da classe EventArgs.
Use EventHandler<TEventArgs> para passar dados para o processador, conforme mostrado a seguir.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // registo de eventos bl.StartProcess(); } // manipulação de eventos public static void bl_ProcessCompleted(object sender, bool IsSuccessful) { Console.WriteLine("Processo " + (IsSuccessful ? "Completed Successfully" : "failed"); } } public class ProcessBusinessLogic { // Use a declaração de EventHandler incorporado para eventos public event EventHandler<bool> ProcessCompleted; public void StartProcess() { try { Console.WriteLine("Processo iniciado!"); // Alguns código aqui... OnProcessCompleted(true); } catch(Exception ex) { OnProcessCompleted(false); } } protected virtual void OnProcessCompleted(bool IsSuccessful) { ProcessCompleted?.Invoke(this, IsSuccessful); } }
No exemplo acima, passamos um valor booleano único para o processador para indicar se o processo foi concluído com sucesso.
Se desejar passar vários valores como dados do evento, pode criar uma classe derivada da classe base EventArgs, conforme mostrado a seguir.
class ProcessEventArgs : EventArgs { public bool IsSuccessful { get; set; } public DateTime CompletionTime { get; set; } }
O exemplo a seguir demonstra como passar a classe ProcessEventArgs personalizada para o processador.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // registo de eventos bl.StartProcess(); } // manipulação de eventos public static void bl_ProcessCompleted(object sender, ProcessEventArgs e) { Console.WriteLine("Processo " + (e.IsSuccessful ? "Concluído com sucesso" : "falhou")); Console.WriteLine("Tempo de conclusão: " + e.CompletionTime.ToLongDateString()); } } public class ProcessBusinessLogic { // Use a declaração de EventHandler incorporado para eventos public event EventHandler<ProcessEventArgs> ProcessCompleted; public void StartProcess() { var data = new ProcessEventArgs(); try { Console.WriteLine("Processo iniciado!"); // Alguns código aqui... data.IsSuccessful = true; data.CompletionTime = DateTime.Now; OnProcessCompleted(data); } catch(Exception ex) { data.IsSuccessful = false; data.CompletionTime = DateTime.Now; OnProcessCompleted(data); } } protected virtual void OnProcessCompleted(ProcessEventArgs e) { ProcessCompleted?.Invoke(this, e); } }
Portanto, você pode criar, emitir, registrar e manipular eventos em C#.
Os eventos são uma envoltória de delegados. Isso depende do delegado.
Use a palavra-chave "event" juntamente com a variável do tipo de delegado para declarar eventos.
use os delegados incorporadosEventHandler ouEventHandler <TEventArgs> é usado para eventos comuns.
O classe de publicador lança um evento, enquanto a classe de assinante se registra em um evento e fornece um método de manipulação de eventos.
Nomeie o método que dispara o evento com o nome do evento, começando com 'On'.
A assinatura do método do manipulador deve coincidir com a assinatura do delegado.
Use+ O operador = registra eventos. Use -O operador = desregista, não pode usar o operador =.
Use EventHandler <TEventArgs> para passar dados de eventos.
Derive a classe base EventArgs para criar classes de dados de eventos personalizadas.
Os eventos podem ser declarados como estáticos, virtuais, selados e abstratos (static, virtual, sealed, abstract).
A interface pode incluir eventos como membros.
Se houver múltiplos assinantes, o manipulador de eventos será chamado simultaneamente.