Compartir a través de


Cómo: Implementar eventos de interfaz (Guía de programación de C#)

Actualización: noviembre 2007

Una interfaz puede declarar un evento. El ejemplo siguiente muestra cómo implementar eventos de interfaz en una clase. Básicamente, las reglas son las mismas que cuando se implementa cualquier método de interfaz o propiedad.

Para implementar eventos de interfaz en una clase

  • Declare el evento en la clase y, a continuación, invóquelo en las áreas adecuadas.

    public interface IDrawingObject
    {
        event EventHandler ShapeChanged;
    }
    public class MyEventArgs : EventArgs {…}
    public class Shape : IDrawingObject
    {
        event EventHandler ShapeChanged;
        void ChangeShape()
        {
            // Do something before the event…
            OnShapeChanged(new MyEventsArgs(…));
            // or do something after the event. 
        }
        protected virtual void OnShapeChanged(MyEventArgs e)
        {
            if(ShapeChanged != null)
            {
               ShapeChanged(this, e);
            }
        }
    }
    

Ejemplo

El ejemplo siguiente muestra cómo controlar la situación menos común en la que la clase se hereda de dos o más interfaces y cada interfaz tiene un evento con el mismo nombre. En esta situación, debe proporcionar una implementación de interfaz explícita para al menos uno de los eventos. Cuando escriba una implementación de interfaz explícita para un evento, también debe incluir los descriptores de acceso a eventos add y remove. Normalmente, estos descriptores los proporciona el compilador, pero en este caso no es así.

Al proporcionar sus propios descriptores de acceso, puede especificar si los dos eventos se representan mediante el mismo evento en la clase o mediante eventos diferentes. Por ejemplo, si los eventos deben provocarse en momentos diferentes según las especificaciones de la interfaz, luego puede asociar cada evento a una implementación distinta en la clase. En el ejemplo siguiente, los suscriptores determinan qué evento OnDraw se recibirá convirtiendo la referencia de la forma en IShape o 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.
*/

Vea también

Tareas

Cómo: Producir eventos de una clase base en clases derivadas (Guía de programación de C#)

Conceptos

Guía de programación de C#

Referencia

Eventos (Guía de programación de C#)

Delegados (Guía de programación de C#)

Implementación explícita de interfaz (Guía de programación de C#)