Como publicar eventos em conformidade com as Diretrizes do .NET (Guia de Programação em C#)
O procedimento a seguir demonstra como adicionar eventos que seguem o padrão .NET às suas classes e structs. Todos os eventos na biblioteca de classes do .NET são baseados no EventHandler delegado , que é definido da seguinte forma:
public delegate void EventHandler(object sender, EventArgs e);
Observação
.NET Framework 2.0 introduz uma versão genérica desse delegado, EventHandler<TEventArgs>. Os exemplos a seguir mostram como usar as duas versões.
Embora os eventos em classes que você define possam ser baseados em qualquer tipo delegado válido, mesmo delegados que retornam um valor, geralmente é recomendável que você basee seus eventos no padrão .NET EventHandlerusando , conforme mostrado no exemplo a seguir.
O nome EventHandler
pode levar a um pouco de confusão, pois ele não trata realmente o evento. Os EventHandlergenéricos , e são EventHandler<TEventArgs> tipos delegados. Um método ou expressão lambda cuja assinatura corresponde à definição de delegado é o manipulador de eventos e será invocado quando o evento for gerado.
Publicar eventos com base no padrão EventHandler
(Ignore esta etapa e vá para a Etapa 3a se você não tiver que enviar dados personalizados com seu evento.) Declare a classe para seus dados personalizados em um escopo visível para suas classes de editor e assinante. Em seguida, adicione os membros necessários para manter seus dados de evento personalizados. Neste exemplo, uma cadeia de caracteres simples é retornada.
public class CustomEventArgs : EventArgs { public CustomEventArgs(string message) { Message = message; } public string Message { get; set; } }
(Ignore esta etapa se você estiver usando a versão genérica do EventHandler<TEventArgs>.) Declare um delegado em sua classe de publicação. Dê a ele um nome que termine com
EventHandler
. O segundo parâmetro especifica o tipoEventArgs
personalizado.public delegate void CustomEventHandler(object sender, CustomEventArgs args);
Declare o evento em sua classe de publicação, usando uma das etapas a seguir.
Se você não tiver uma classe EventArgs personalizada, o tipo de evento será o delegado EventHandler não genérico. Você não precisa declarar o delegado porque ele já está declarado no namespace System que está incluído quando você cria seu projeto do C#. Adicione o seguinte código à sua classe publicadora.
public event EventHandler RaiseCustomEvent;
Se você estiver usando a versão não genérica de EventHandler e você tem uma classe personalizada derivada de EventArgs, declare o evento dentro de sua classe de publicação e use o delegado da etapa 2 como o tipo.
public event CustomEventHandler RaiseCustomEvent;
Se você estiver usando a versão genérica, não é necessário um delegado personalizado. Em vez disso, na sua classe de publicação, especifique o tipo de evento como
EventHandler<CustomEventArgs>
, substituindo o nome da sua própria classe entre os colchetes angulares.public event EventHandler<CustomEventArgs> RaiseCustomEvent;
Exemplo
O exemplo a seguir demonstra as etapas anteriores, usando uma classe EventArgs personalizada e o EventHandler<TEventArgs> como o tipo de evento.
using System;
namespace DotNetEvents
{
// Define a class to hold custom event info
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
}
// Class that publishes an event
class Publisher
{
// Declare the event using EventHandler<T>
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
public void DoSomething()
{
// Write some code that does something useful here
// then raise the event. You can also raise an event
// before you execute a block of code.
OnRaiseCustomEvent(new CustomEventArgs("Event triggered"));
}
// Wrap event invocations inside a protected virtual method
// to allow derived classes to override the event invocation behavior
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent;
// Event will be null if there are no subscribers
if (raiseEvent != null)
{
// Format the string to send inside the CustomEventArgs parameter
e.Message += $" at {DateTime.Now}";
// Call to raise the event.
raiseEvent(this, e);
}
}
}
//Class that subscribes to an event
class Subscriber
{
private readonly string _id;
public Subscriber(string id, Publisher pub)
{
_id = id;
// Subscribe to the event
pub.RaiseCustomEvent += HandleCustomEvent;
}
// Define what actions to take when the event is raised.
void HandleCustomEvent(object sender, CustomEventArgs e)
{
Console.WriteLine($"{_id} received this message: {e.Message}");
}
}
class Program
{
static void Main()
{
var pub = new Publisher();
var sub1 = new Subscriber("sub1", pub);
var sub2 = new Subscriber("sub2", pub);
// Call the method that raises the event.
pub.DoSomething();
// Keep the console window open
Console.WriteLine("Press any key to continue...");
Console.ReadLine();
}
}
}