Продолжаем разбор обобщений и в этом видео я расскажу тебе зачем нужны обобщенные делегаты, как они работают и самое главное подробно объясню такие понятия как инвариантность, ковориантность и контрвариантность. Многих пугают эти слова, но на самом деле - все не так уж сложно. Ну а еще мы чуть подробнее посмотрим на особенности обобщенных методов
Обобщенные делегаты
Для чего же нужны обобщенные делегаты? А ответ прост - чтобы можно было передать в метод обратного вызова любой тип объекта, сохраняя безопасность типов. А как приятный бонус - если передается значимый тип, то упаковка выполняться не будет.
Что из себя представляет делегат на самом деле? Мы немного затронули тему делегатов, когда разбирали события, но подробно мы будем говорить о них в одном из будущих видео, но сейчас для понимания нам необходимо знать, что по своей сути делегаты тоже являются классами с четырьмя обязательными методами:
- Конструктор
- Invoke
- BeginInvoke
- EndInvoke
Контрвариантные и ковариантные аргументы-типы
Для начала нужно вспомнить, какими могут быть аргументы типа:
- Инвариантные. Параметр-тип не может меняться. Используется по умолчанию.
- Контрвариантные. Параметр-тип может быть преобразован к производному классу, то есть наследнику. Обозначается ключевым словом in. Должен использоваться во входной позиции, например, как аргумент метода.
- Ковариантные. Параметр-тип может быть преобразован к базовому классу, то есть предку. Обозначается ключевым словом out. Должен использоваться в выходной позиции, например, как возвращаемое значение.
Для делегатов, каждый из аргументов типов должен быть контр- или ко- вариантным. Благодаря этому можно выполнять приведение экземпляра обобщенного делегата к тому же типу делегата с другим параметром типом.
Обобщенные методы
У методов есть сразу два способа использования обобщений. Во-первых, они могут применять тип параметр в качестве собственного аргумента, возвращаемого значения или внутренней переменной. Во-вторых же, они могут определять свои собственные параметры типа, применяющиеся в нем, аналогично параметрам типа класса
Обобщенные методы и выведение типов
Все это конечно прекрасно, но так как программисты очень ленивые люди и каждый раз в ручную указывать типы совершенно не хочется, то был создан механизм выведения типов (type inference). Компилятор пытается на основе передаваемых аргументов логически вывести используемые типы данных в обобщенном методе, чтобы не писать это ручками.
Обобщения и другие члены
В языке C# не у всех членов типа могут быть параметры типа. Например их нет у:
- Свойств
- Индексаторов
- Событий
- Операторов (+, -, *, / и т.д.)
- Конструкторов
- Деструкторов
Но использовать определенные у класса параметры типа можно в них использовать. Такое решение было принято разработчиками компании Microsoft, потому что вероятность применения обобщений к этим членам достаточна маленькая, а разработка синтаксиса для этого потребовала бы много усилий и усложнила чтение и понимание кода.
Кроме того, рекомендую прочитать статью Сколько времени нужно, чтобы стать программистом? А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.