Страницы

Поиск по вопросам

четверг, 2 мая 2019 г.

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

Есть такой делегат
delegate void Del(string z);
И ему присваивается метод
public void Foo(object z) {
}
Присваивание происходит нормально, за счет вариантности. Однако если в параметре делегата стринг поменять на int тогда компилятор уже возмущается. Почему ? Полагаю, что это как-то связано с ссылочным/структурным типом. Но ведь все они идут от object


Ответ

Вы правы, вариантность делегатов ограничена ссылочными типами.
Вот нормативная цитата из C# language reference (лежит в \VC#\Specifications\1033\CSharp Language Specification.docx), раздел 15.2 (перевод мой):
15.2 Совместимость делегатов
Метод или делегат M называется совместимым с делегатным типом D, если выполняются следующие условия:
У D и M одинаковое количество параметров, и каждый параметр в D имеет одинаковые модификаторы ref/out, как и соответствующий параметр в M Для каждого параметра, не содержащего ref/out, существует тождественное преобразование (§6.1.1) или неявное ссылочное преобразование (§6.1.6) из типа параметра в D в тип соответствующего параметра в M Для каждого ref-/out-параметра, тип параметра в D в точности тот же, что и в M Существует тождественное или неявное ссылочное преобразование из возвращаемого типа в M к возвращаемому типу в D

Это значит, что типы параметром должны быть либо одинаковы (с точностью до разницы между object и dynamic), либо тип параметра должен быть ссылочным подтипом типа параметра в D. Это исключает значимые типы.

Комментариев нет:

Отправить комментарий