Ковариантность и контравариантность делегатов

92

Делегаты становятся еще более гибкими средствами программирования благодаря двум свойствам: ковариантности и контравариантности. Как правило, метод, передаваемый делегату, должен иметь такой же возвращаемый тип и сигнатуру, как и делегат. Но в отношении производных типов это правило оказывается не таким строгим благодаря ковариантности и контравариантности. В частности, ковариантность позволяет присвоить делегату метод, возвращаемым типом которого служит класс, производный от класса, указываемого в возвращаемом типе делегата. А контравариантность позволяет присвоить делегату метод, типом параметра которого служит класс, являющийся базовым для класса, указываемого в объявлении делегата.

Ниже приведен пример, демонстрирующий ковариантность и контравариантность:

using System;

namespace ConsoleApplication1
{
    delegate Name UI (FamilyAndName obj);

    public class Name
    {
        public string myName;
    }

    public class FamilyAndName : Name
    {
        public string Family;
    }

    public class UserInfo
    {
        public static Name UIName(Name obj)
        {
            obj.myName = "Имя пользователя: \"" + obj.myName + "\"";
            return obj;
        }

        public static FamilyAndName UIFamilyName(FamilyAndName obj)
        {
            obj.Family = "Имя и фамилия: \"" + obj.myName + " " + obj.Family + "\"";
            return obj;
        }
    }

    class Program
    {
        static void Main()
        {
            // Пример ковариантности
            // Можно использовать метод, возвращаемым типом параметра которого 
            // является производный класс
            UI user1 = UserInfo.UIFamilyName;

            // Пример контравариантности
            // Можно использовать метод, аргументом которого является
            // базовый класс
            user1 = UserInfo.UIName;
        }
    }
}

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

Пройди тесты
Лучший чат для C# программистов