Partilhar via


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 padrão para suas classes e estruturas. Todos os eventos na biblioteca de classes .NET são baseados no EventHandler delegado, que é definido da seguinte maneira:

public delegate void EventHandler(object? sender, EventArgs e);

Nota

O .NET Framework 2.0 introduz uma versão genérica deste delegado, EventHandler<TEventArgs>. Os exemplos a seguir mostram como usar ambas as versões.

Embora os eventos em classes que você define possam ser baseados em qualquer tipo de delegado válido, até mesmo delegados que retornam um valor, geralmente é recomendável que você baseie seus eventos no padrão .NET usando , conforme EventHandlermostrado no exemplo a seguir.

O nome EventHandler pode levar a um pouco de confusão, pois não lida com o evento. O EventHandler, e genérico EventHandler<TEventArgs> são 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

  1. (Ignore esta etapa e vá para a Etapa 3a se não precisar enviar dados personalizados com seu evento.) Declare a classe para seus dados personalizados em um escopo que seja visível para suas classes de editor e assinante. Em seguida, adicione os membros necessários para armazenar 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; }
    }
    
  2. (Ignore esta etapa se estiver usando a versão genérica do EventHandler<TEventArgs>.) Declare um delegado em sua classe de publicação. Dê-lhe um nome que termine com EventHandler. O segundo parâmetro especifica seu tipo personalizado EventArgs .

    public delegate void CustomEventHandler(object? sender, CustomEventArgs args);
    
  3. Declare o evento em sua classe de publicação usando uma das etapas a seguir.

    1. Se você não tiver nenhuma classe EventArgs personalizada, seu tipo de evento será o delegado EventHandler não genérico. Não é necessário declarar o delegado porque ele já está declarado System no namespace incluído quando você cria seu projeto C#. Adicione o seguinte código à sua classe de editor.

      public event EventHandler? RaiseCustomEvent;
      
    2. Se você estiver usando a versão não genérica do EventHandler e tiver uma classe personalizada derivada de , declare seu evento dentro de sua classe de EventArgspublicação e use seu delegado da etapa 2 como o tipo.

      public event CustomEventHandler? RaiseCustomEvent;
      
    3. Se você estiver usando a versão genérica, não precisará de um delegado personalizado. Em vez disso, na classe de publicação, especifique o tipo de evento como EventHandler<CustomEventArgs>, substituindo o nome da sua própria classe entre colchetes angulares.

      public event EventHandler<CustomEventArgs>? RaiseCustomEvent;
      

Exemplo

O exemplo a seguir demonstra as etapas anteriores usando uma classe EventArgs personalizada e 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();
        }
    }
}

Consulte também