Поделиться через


Практическое руководство. Реализация событий интерфейса (Руководство по программированию в C#)

Интерфейс может объявить событие. В следующем примере показана реализация событий интерфейса в классе. В принципе, применяются те же правила, что и при реализации любого метода интерфейса или свойства.

Реализация событий интерфейса в классе

  • Объявите событие в классе и вызовите его в соответствующих областях.

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

Пример

В следующем примере показано, как действовать в не очень распространенном случае, когда класс наследует от двух или более интерфейсов и каждый интерфейс имеет событие с тем же именем. В такой ситуации, по меньшей мере, для одного из событий следует предоставить явную реализацию интерфейса. При написании явной реализации интерфейса для события необходимо также написать методы доступа к событию add и remove. Как правило, они обеспечиваются компилятором, в этом случае компилятор не сможет предоставить их.

При помощи собственных методов доступа можно определить, будут ли два события представлены одним событием в классе или разными событиями. Например, если события должны инициироваться в разное время в зависимости от требований интерфейса, то каждое событие можно связать с отдельной реализацией в классе. В следующем примере подписчики определяют, какое событие OnDraw они получат путем приведения ссылки на форму к IShape или 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.
*/

См. также

Задачи

Практическое руководство. Создание событий базового класса в производных классах (Руководство по программированию в C#)

Ссылки

События (Руководство по программированию в C#)

Делегаты (Руководство по программированию на C#)

Явная реализация интерфейса (Руководство по программированию в C#)

Основные понятия

Руководство по программированию на C#