Share via


Publicera händelser som överensstämmer med .NET-riktlinjer (C#-programmeringsguide)

Följande procedur visar hur du lägger till händelser som följer standardmönstret för .NET i dina klasser och structs. Alla händelser i .NET-klassbiblioteket baseras på ombudet EventHandler , vilket definieras på följande sätt:

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

Kommentar

.NET Framework 2.0 introducerar en allmän version av det här ombudet, EventHandler<TEventArgs>. I följande exempel visas hur du använder båda versionerna.

Även om händelser i klasser som du definierar kan baseras på valfri giltig delegattyp, även ombud som returnerar ett värde, rekommenderar vi vanligtvis att du baserar dina händelser på .NET-mönstret med hjälp EventHandlerav , som du ser i följande exempel.

Namnet EventHandler kan leda till lite förvirring eftersom det faktiskt inte hanterar händelsen. , EventHandleroch generiska EventHandler<TEventArgs> är ombudstyper. En metod eller lambda-uttryck vars signatur matchar delegatdefinitionen är händelsehanteraren och anropas när händelsen aktiveras.

Publicera händelser baserat på EventHandler-mönstret

  1. (Hoppa över det här steget och gå till Steg 3a om du inte behöver skicka anpassade data med din händelse.) Deklarera klassen för dina anpassade data i ett omfång som är synligt för både utgivaren och prenumerantklasserna. Lägg sedan till de medlemmar som krävs för att lagra dina anpassade händelsedata. I det här exemplet returneras en enkel sträng.

    public class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string message)
        {
            Message = message;
        }
    
        public string Message { get; set; }
    }
    
  2. (Hoppa över det här steget om du använder den allmänna versionen av EventHandler<TEventArgs>.) Deklarera ett ombud i publiceringsklassen. Ge den ett namn som slutar med EventHandler. Den andra parametern anger din anpassade EventArgs typ.

    public delegate void CustomEventHandler(object? sender, CustomEventArgs args);
    
  3. Deklarera händelsen i publiceringsklassen med något av följande steg.

    1. Om du inte har någon anpassad EventArgs-klass blir din händelsetyp det icke-generiska EventHandler-ombudet. Du behöver inte deklarera ombudet eftersom det redan har deklarerats i System namnområdet som ingår när du skapar C#-projektet. Lägg till följande kod i utgivarklassen.

      public event EventHandler? RaiseCustomEvent;
      
    2. Om du använder den icke-generiska versionen av EventHandler och du har en anpassad klass härledd från EventArgsdeklarerar du händelsen i publiceringsklassen och använder ditt ombud från steg 2 som typ.

      public event CustomEventHandler? RaiseCustomEvent;
      
    3. Om du använder den allmänna versionen behöver du inte ett anpassat ombud. I din publiceringsklass anger du i stället händelsetypen som EventHandler<CustomEventArgs>, och ersätter namnet på din egen klass mellan vinkelparenteserna.

      public event EventHandler<CustomEventArgs>? RaiseCustomEvent;
      

Exempel

I följande exempel visas föregående steg med hjälp av en anpassad EventArgs-klass och EventHandler<TEventArgs> som händelsetyp.

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();
        }
    }
}

Se även