Ковариация и контрвариация в делегатах (руководство по программированию в C#)

Обновлен: Ноябрь 2007

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

Пример 1 (ковариация)

Описание

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

Код

class Mammals
{
}

class Dogs : Mammals
{
}

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

    public static Mammals FirstHandler()
    {
        return null;
    }

    public static Dogs SecondHandler()
    {
        return null;
    }

    static void Main()
    {
        HandlerMethod handler1 = FirstHandler;

        // Covariance allows this delegate.
        HandlerMethod handler2 = SecondHandler;
    }
}

Пример 2 (контрвариация)

Описание

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

Код

System.DateTime lastActivity;
public Form1()
{
    InitializeComponent();

    lastActivity = new System.DateTime();
    this.textBox1.KeyDown += this.MultiHandler; //works with KeyEventArgs
    this.button1.MouseClick += this.MultiHandler; //works with MouseEventArgs

}

// Event hander for any event with an EventArgs or
// derived class in the second parameter
private void MultiHandler(object sender, System.EventArgs e)
{
    lastActivity = System.DateTime.Now;
}

См. также

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

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

Ссылки

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

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

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