Использование вариативности в делегатах

C Sharp > Использование вариативности в делегатах
06.12.2016 14:54:11



Статья:

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

Описание

В данном примере демонстрируется использование делегатов с методами, типы возвращаемых значений которых являются производными от типа возвращаемого значения в сигнатуре делегата. Тип данных, возвращаемый DogsHandler, является типом Dogs, производным от заданного в делегате типа Mammals.

Код

    class Mammals{}
    class Dogs : Mammals{}

    class Program
    {
        // Define the delegate.
        public delegate Mammals HandlerMethod();

        public static Mammals MammalsHandler()
        {
            return null;
        }

        public static Dogs DogsHandler()
        {
            return null;
        }

        static void Test()
        {
            HandlerMethod handlerMammals = MammalsHandler;

            // Covariance enables this assignment.
            HandlerMethod handlerDogs = DogsHandler;
        }
    }

Описание

В данном примере демонстрируется использование делегатов с методами, параметры типа которых являются базовыми типами типа параметра сигнатуры делегата. Контравариация позволяет использовать один обработчик событий вместо нескольких. Например, можно создать обработчик событий, принимающий параметр ввода EventArgs, и использовать его с событием Button.MouseClick, которое отправляет тип MouseEventArgs как параметр, а также с событием TextBox.KeyDown, которое отправляет параметр KeyEventArgs.

Код

        // Event hander that accepts a parameter of the EventArgs type.
        private void MultiHandler(object sender, System.EventArgs e)
        {
            label1.Text = System.DateTime.Now.ToString();
        }

        public Form1()
        {
            InitializeComponent();

            // You can use a method that has an EventArgs parameter,
            // although the event expects the KeyEventArgs parameter.
            this.button1.KeyDown += this.MultiHandler;

            // You can use the same method 
            // for an event that expects the MouseEventArgs parameter.
            this.button1.MouseClick += this.MultiHandler;

        }