Procedimiento Publicar eventos que cumplan las directrices de .NET Framework (Guía de programación de C#)How to: Publish Events that Conform to .NET Framework Guidelines (C# Programming Guide)

En el siguiente procedimiento se muestra cómo agregar eventos que cumplan el patrón .NET Framework estándar a las clases y structs.The following procedure demonstrates how to add events that follow the standard .NET Framework pattern to your classes and structs. Todos los eventos de la biblioteca de clases .NET Framework se basan en el delegado EventHandler, que se define de la siguiente manera:All events in the .NET Framework class library are based on the EventHandler delegate, which is defined as follows:

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

Nota

.NET Framework 2.0.NET Framework 2.0 incluye una versión genérica de este delegado, EventHandler<TEventArgs>.The .NET Framework 2.0.NET Framework 2.0 introduces a generic version of this delegate, EventHandler<TEventArgs>. En los siguientes ejemplos se muestra cómo usar las dos versiones.The following examples show how to use both versions.

Aunque los eventos de las clases que defina se pueden basar en cualquier tipo de delegado válido, incluidos los delegados que devuelven un valor, por lo general se recomienda que base los eventos en el patrón .NET Framework mediante EventHandler, como se muestra en el ejemplo siguiente.Although events in classes that you define can be based on any valid delegate type, even delegates that return a value, it is generally recommended that you base your events on the .NET Framework pattern by using EventHandler, as shown in the following example.

Para publicar eventos basados en el patrón EventHandlerTo publish events based on the EventHandler pattern

  1. (Omita este paso y vaya al paso 3a si no tiene que enviar datos personalizados con el evento). Declare la clase de los datos personalizados en un ámbito que sea visible para las clases de publicador y suscriptor.(Skip this step and go to Step 3a if you do not have to send custom data with your event.) Declare the class for your custom data at a scope that is visible to both your publisher and subscriber classes. Luego, agregue los miembros necesarios para almacenar los datos de eventos personalizados.Then add the required members to hold your custom event data. En este ejemplo se devuelve una cadena simple.In this example, a simple string is returned.

    public class CustomEventArgs : EventArgs  
    {  
        public CustomEventArgs(string s)  
        {  
            msg = s;  
        }  
        private string msg;  
        public string Message  
        {  
            get { return msg; }  
        }   
    }  
    
  2. (Omita este paso si usa la versión genérica de EventHandler<TEventArgs>). Declare un delegado en la clase de publicación.(Skip this step if you are using the generic version of EventHandler<TEventArgs> .) Declare a delegate in your publishing class. Asígnele un nombre que acabe por EventHandler.Give it a name that ends with EventHandler. El segundo parámetro especifica el tipo EventArgs personalizado.The second parameter specifies your custom EventArgs type.

    public delegate void CustomEventHandler(object sender, CustomEventArgs a);  
    
  3. Declare el evento en la clase de publicación llevando a cabo uno de los siguientes pasos.Declare the event in your publishing class by using one of the following steps.

    1. Si no tiene ninguna clase EventArgs personalizada, el tipo Event será el delegado EventHandler no genérico.If you have no custom EventArgs class, your Event type will be the non-generic EventHandler delegate. No es necesario declarar el delegado, porque ya está declarado en el espacio de nombres System que se incluye al crear el proyecto de C#.You do not have to declare the delegate because it is already declared in the System namespace that is included when you create your C# project. Agregue el código siguiente a la clase de publicador.Add the following code to your publisher class.

      public event EventHandler RaiseCustomEvent;  
      
    2. Si usa la versión no genérica de EventHandler y tiene una clase personalizada derivada de EventArgs, declare el evento dentro de la clase de publicación y use el delegado del paso 2 como tipo.If you are using the non-generic version of EventHandler and you have a custom class derived from EventArgs, declare your event inside your publishing class and use your delegate from step 2 as the type.

      public event CustomEventHandler RaiseCustomEvent;  
      
    3. Si usa la versión genérica, no necesita ningún delegado personalizado.If you are using the generic version, you do not need a custom delegate. En su lugar, en la clase de publicación, especifique el tipo de evento como EventHandler<CustomEventArgs>, sustituyendo el nombre de su propia clase que aparece entre corchetes angulares.Instead, in your publishing class, you specify your event type as EventHandler<CustomEventArgs>, substituting the name of your own class between the angle brackets.

      public event EventHandler<CustomEventArgs> RaiseCustomEvent;  
      

EjemploExample

En el siguiente ejemplo se muestran los pasos anteriores mediante el uso de una clase EventArgs personalizada y EventHandler<TEventArgs> como tipo de evento.The following example demonstrates the previous steps by using a custom EventArgs class and EventHandler<TEventArgs> as the event type.

namespace DotNetEvents
{
    using System;
    using System.Collections.Generic;

    // Define a class to hold custom event info
    public class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string s)
        {
            message = s;
        }
        private string message;

        public string Message
        {
            get { return message; }
            set { message = value; }
        }
    }

    // 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("Did something"));

        }

        // 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> handler = RaiseCustomEvent;

            // Event will be null if there are no subscribers
            if (handler != null)
            {
                // Format the string to send inside the CustomEventArgs parameter
                e.Message += $" at {DateTime.Now}";

                // Use the () operator to raise the event.
                handler(this, e);
            }
        }
    }

    //Class that subscribes to an event
    class Subscriber
    {
        private string id;
        public Subscriber(string ID, Publisher pub)
        {
            id = ID;
            // Subscribe to the event using C# 2.0 syntax
            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: {0}", e.Message);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Publisher pub = new Publisher();
            Subscriber sub1 = new Subscriber("sub1", pub);
            Subscriber sub2 = new Subscriber("sub2", pub);

            // Call the method that raises the event.
            pub.DoSomething();

            // Keep the console window open
            Console.WriteLine("Press Enter to close this window.");
            Console.ReadLine();

        }
    }
}

Vea tambiénSee also