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 para classes e structs. Todos os eventos na biblioteca de classes do .NET se baseiam no delegado EventHandler, que é definido da seguinte maneira:
public delegate void EventHandler(object? sender, EventArgs e);
Observação
O .NET Framework 2.0 apresenta uma versão genérica desse delegado, o EventHandler<TEventArgs>. Os exemplos a seguir mostram como usar as duas versões.
Embora os eventos nas classes que você define possam ser baseados em qualquer tipo delegado válido, até mesmo nos delegados que retornam um valor, é geralmente recomendável que você baseie seus eventos no padrão .NET usando o EventHandler, conforme mostrado no exemplo a seguir.
O nome EventHandler
pode levar a um pouco de confusão, pois ele, na verdade, não lida com o evento. Os tipos EventHandler e os tipos EventHandler<TEventArgs> genéricos são delegados. Um método ou expressão lambda cuja assinatura corresponda à definição do delegado é o manipulador de eventos e será invocada quando o evento for gerado.
Publicar eventos com base no padrão EventHandler
(Ignore esta etapa e vá para a 3ª Etapa se você não precisar enviar dados personalizados com o evento.) Declare a classe para seus dados personalizados em um escopo visível para suas classes de publicador 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ê um nome que termine com
EventHandler
. O segundo parâmetro especifica o tipo personalizadoEventArgs
.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.
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();
}
}
}
Confira também
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de