Delen via


Interface-gebeurtenissen implementeren (C#-programmeerhandleiding)

Een interface kan een gebeurtenis declareren. In het volgende voorbeeld ziet u hoe u interface-gebeurtenissen in een klasse implementeert. In principe zijn de regels hetzelfde als wanneer u een interfacemethode of eigenschap implementeert.

Interface-gebeurtenissen in een klasse implementeren

Declareer de gebeurtenis in uw klas en roep deze vervolgens aan in de juiste gebieden.

namespace ImplementInterfaceEvents  
{  
    public interface IDrawingObject  
    {  
        event EventHandler ShapeChanged;  
    }  
    public class MyEventArgs : EventArgs
    {  
        // class members  
    }  
    public class Shape : IDrawingObject  
    {  
        public event EventHandler ShapeChanged;  
        void ChangeShape()  
        {  
            // Do something here before the event…  

            OnShapeChanged(new MyEventArgs(/*arguments*/));  

            // or do something here after the event.
        }  
        protected virtual void OnShapeChanged(MyEventArgs e)  
        {  
            ShapeChanged?.Invoke(this, e);  
        }  
    }  

}  

Opmerking

In het volgende voorbeeld ziet u hoe u de minder gangbare situatie kunt afhandelen waarin uw klasse overgaat van twee of meer interfaces en elke interface een gebeurtenis met dezelfde naam heeft. In deze situatie moet u een expliciete interface-implementatie opgeven voor ten minste één van de gebeurtenissen. Wanneer u een expliciete interface-implementatie schrijft voor een gebeurtenis, moet u ook de add toegangs- en remove gebeurtenistoegangsors schrijven. Normaal gesproken worden deze geleverd door de compiler, maar in dit geval kan de compiler deze niet leveren.

Door uw eigen accessors op te geven, kunt u opgeven of de twee gebeurtenissen worden vertegenwoordigd door dezelfde gebeurtenis in uw klas of door verschillende gebeurtenissen. Als de gebeurtenissen bijvoorbeeld op verschillende tijdstippen moeten worden gegenereerd volgens de interfacespecificaties, kunt u elke gebeurtenis koppelen aan een afzonderlijke implementatie in uw klasse. In het volgende voorbeeld bepalen abonnees welke OnDraw gebeurtenis ze ontvangen door de shapereferentie te casten naar een IShape of een IDrawingObject.

namespace WrapTwoInterfaceEvents
{
    using System;

    public interface IDrawingObject
    {
        // Raise this event before drawing
        // the object.
        event EventHandler OnDraw;
    }
    public interface IShape
    {
        // Raise this event after drawing
        // the shape.
        event EventHandler OnDraw;
    }

    // Base class event publisher inherits two
    // interfaces, each with an OnDraw event
    public class Shape : IDrawingObject, IShape
    {
        // Create an event for each interface event
        event EventHandler PreDrawEvent;
        event EventHandler PostDrawEvent;

        object objectLock = new Object();

        // Explicit interface implementation required.
        // Associate IDrawingObject's event with
        // PreDrawEvent
        #region IDrawingObjectOnDraw
        event EventHandler IDrawingObject.OnDraw
        {
            add
            {
                lock (objectLock)
                {
                    PreDrawEvent += value;
                }
            }
            remove
            {
                lock (objectLock)
                {
                    PreDrawEvent -= value;
                }
            }
        }
        #endregion
        // Explicit interface implementation required.
        // Associate IShape's event with
        // PostDrawEvent
        event EventHandler IShape.OnDraw
        {
            add
            {
                lock (objectLock)
                {
                    PostDrawEvent += value;
                }
            }
            remove
            {
                lock (objectLock)
                {
                    PostDrawEvent -= value;
                }
            }
        }

        // For the sake of simplicity this one method
        // implements both interfaces.
        public void Draw()
        {
            // Raise IDrawingObject's event before the object is drawn.
            PreDrawEvent?.Invoke(this, EventArgs.Empty);

            Console.WriteLine("Drawing a shape.");

            // Raise IShape's event after the object is drawn.
            PostDrawEvent?.Invoke(this, EventArgs.Empty);
        }
    }
    public class Subscriber1
    {
        // References the shape object as an IDrawingObject
        public Subscriber1(Shape shape)
        {
            IDrawingObject d = (IDrawingObject)shape;
            d.OnDraw += d_OnDraw;
        }

        void d_OnDraw(object sender, EventArgs e)
        {
            Console.WriteLine("Sub1 receives the IDrawingObject event.");
        }
    }
    // References the shape object as an IShape
    public class Subscriber2
    {
        public Subscriber2(Shape shape)
        {
            IShape d = (IShape)shape;
            d.OnDraw += d_OnDraw;
        }

        void d_OnDraw(object sender, EventArgs e)
        {
            Console.WriteLine("Sub2 receives the IShape event.");
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            Shape shape = new Shape();
            Subscriber1 sub = new Subscriber1(shape);
            Subscriber2 sub2 = new Subscriber2(shape);
            shape.Draw();

            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}
/* Output:
    Sub1 receives the IDrawingObject event.
    Drawing a shape.
    Sub2 receives the IShape event.
*/

Zie ook