Share via


Gebeurtenissen publiceren die voldoen aan .NET-richtlijnen (C#-programmeerhandleiding)

In de volgende procedure ziet u hoe u gebeurtenissen toevoegt die het standaard .NET-patroon volgen aan uw klassen en structs. Alle gebeurtenissen in de .NET-klassebibliotheek zijn gebaseerd op de EventHandler gemachtigde, die als volgt wordt gedefinieerd:

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

Notitie

.NET Framework 2.0 introduceert een algemene versie van deze gemachtigde. EventHandler<TEventArgs> In de volgende voorbeelden ziet u hoe u beide versies gebruikt.

Hoewel gebeurtenissen in klassen die u definieert, kunnen worden gebaseerd op elk geldig type gemachtigde, zelfs gemachtigden die een waarde retourneren, wordt het over het algemeen aanbevolen dat u uw gebeurtenissen baseert op het .NET-patroon met behulp van EventHandler, zoals wordt weergegeven in het volgende voorbeeld.

De naam EventHandler kan tot verwarring leiden omdat deze de gebeurtenis niet daadwerkelijk verwerkt. De EventHandleren algemene EventHandler<TEventArgs> typen zijn gedelegeerden. Een methode of lambda-expressie waarvan de handtekening overeenkomt met de definitie van de gemachtigde, is de gebeurtenis-handler en wordt aangeroepen wanneer de gebeurtenis wordt gegenereerd.

Gebeurtenissen publiceren op basis van het EventHandler-patroon

  1. (Sla deze stap over en ga naar stap 3a als u geen aangepaste gegevens hoeft te verzenden met uw gebeurtenis.) Declareer de klasse voor uw aangepaste gegevens in een bereik dat zichtbaar is voor zowel uw uitgevers- als abonneeklassen. Voeg vervolgens de vereiste leden toe om uw aangepaste gebeurtenisgegevens op te slaan. In dit voorbeeld wordt een eenvoudige tekenreeks geretourneerd.

    public class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string message)
        {
            Message = message;
        }
    
        public string Message { get; set; }
    }
    
  2. (Sla deze stap over als u de algemene versie van EventHandler<TEventArgs>.) Declareer een gemachtigde in uw publicatieklasse. Geef het een naam die eindigt op EventHandler. Met de tweede parameter wordt uw aangepaste EventArgs type opgegeven.

    public delegate void CustomEventHandler(object? sender, CustomEventArgs args);
    
  3. Declareer de gebeurtenis in uw publicatieklasse met behulp van een van de volgende stappen.

    1. Als u geen aangepaste EventArgs-klasse hebt, is uw gebeurtenistype de niet-algemene EventHandler-gemachtigde. U hoeft de gemachtigde niet te declareren omdat deze al is gedeclareerd in de System naamruimte die is opgenomen bij het maken van uw C#-project. Voeg de volgende code toe aan uw uitgeversklasse.

      public event EventHandler? RaiseCustomEvent;
      
    2. Als u de niet-algemene versie gebruikt en EventHandler u een aangepaste klasse hebt die is afgeleid van EventArgs, declareert u uw gebeurtenis in uw publicatieklasse en gebruikt u uw gemachtigde uit stap 2 als het type.

      public event CustomEventHandler? RaiseCustomEvent;
      
    3. Als u de algemene versie gebruikt, hebt u geen aangepaste gemachtigde nodig. In plaats daarvan geeft u in uw publicatieklasse het gebeurtenistype op als EventHandler<CustomEventArgs>, waarbij u de naam van uw eigen klasse vervangt door de punthaken.

      public event EventHandler<CustomEventArgs>? RaiseCustomEvent;
      

Opmerking

In het volgende voorbeeld ziet u de vorige stappen met behulp van een aangepaste EventArgs-klasse en EventHandler<TEventArgs> als gebeurtenistype.

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

Zie ook