Comment : implémenter des événements d'interface (Guide de programmation C#)

Une interface peut déclarer un événement 8627sbea(v=vs.100).md. L'exemple suivant montre comment implémenter des événements d'interface dans une classe. Fondamentalement, les règles sont les mêmes que lors de l'implémentation d'une propriété ou méthode d'interface.

Pour implémenter des événements d'interface dans une classe

  • Déclarez l'événement dans votre classe, puis appelez-le aux emplacements appropriés.

    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)
            {
                if(ShapeChanged != null)
                {
                   ShapeChanged(this, e);
                }
            }
        }
    
    }
    

Exemple

L'exemple suivant montre comment gérer la situation la moins courante dans laquelle votre classe hérite de deux ou plusieurs interfaces et où chaque interface possède un événement avec le même nom. Dans cette situation, vous devez fournir une implémentation d'interface explicite pour au moins l'un des événements. Lorsque vous écrivez une implémentation d'interface explicite pour un événement, vous devez également écrire les accesseurs d'événement add et remove. Normalement, ceux-ci sont fournis par le compilateur, mais, dans ce cas, le compilateur ne peut pas les proposer.

En fournissant vos propres accesseurs, vous pouvez spécifier si les deux événements sont représentés par le même événement de votre classe, ou par des événements différents. Par exemple, si les événements doivent être déclenchés à des moments différents en fonction des spécifications de l'interface, vous pouvez associer chaque événement à une implémentation distincte de votre classe. Dans l'exemple suivant, les abonnés déterminent quel événement OnDraw ils reçoivent en exécutant un cast de la référence de la forme en une interface IShape ou 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
        event EventHandler IDrawingObject.OnDraw
        {
            add
            {
                lock (objectLock)
                {
                    PreDrawEvent += value;
                }
            }
            remove
            {
                lock (objectLock)
                {
                    PreDrawEvent -= value;
                }
            }
        }
        // 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.
            EventHandler handler = PreDrawEvent;
            if (handler != null)
            {
                handler(this, new EventArgs());
            }
            Console.WriteLine("Drawing a shape.");

            // RaiseIShape's event after the object is drawn.
            handler = PostDrawEvent;
            if (handler != null)
            {
                handler(this, new EventArgs());
            }
        }
    }
    public class Subscriber1
    {
        // References the shape object as an IDrawingObject
        public Subscriber1(Shape shape)
        {
            IDrawingObject d = (IDrawingObject)shape;
            d.OnDraw += new EventHandler(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 += new EventHandler(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.
*/

Voir aussi

Tâches

Comment : déclencher les événements de la classe de base dans les classes dérivées (Guide de programmation C#)

Référence

Événements (Guide de programmation C#)

Délégués (guide de programmation C#)

Implémentation d'interface explicite (Guide de programmation C#)

Concepts

Guide de programmation C#