Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22

Использование контрвариантного типа как типа аргумента

17.04.2019, 15:09. Показов 2055. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Почему разрешено использовать контрвариантный тип как тип аргумента? Разве не может возникнуть ошибки при этом?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.04.2019, 15:09
Ответы с готовыми решениями:

Чем отличаются параметр типа от аргумента типа?
Чем отличаются параметр типа от аргумента типа?

Использование класса, как типа в других классах
Помогите пожалуйста, я совсем запутался =( Задание Вы поймете по ходу, дальше. class Person { //самый обычный класс Персона с...

Как вернуть коллекцию типа OpenedRectangles со всеми свойствами и методами типа Rectangles
Ребят всем привет,подскажите в одном вопросе. Допустим есть некий класс Rectangles: class Rectangles:IComparable<Rectangles> ...

7
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.04.2019, 15:11
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Почему разрешено использовать контрвариантный тип как тип аргумента?
Потому что в этом вся суть контрвариантности
Можно потому, что невозможно использовать "не тот" тип при контрвариантном приведении.
1
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
17.04.2019, 15:14  [ТС]
kolorotur, в почему невозможно?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.04.2019, 15:51
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
почему невозможно?
Предоставьте пример, при котором это возможно.

Добавлено через 27 минут
Вопрос актуален
0
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
17.04.2019, 16:53  [ТС]
kolorotur, в почему невозможно?
Цитата Сообщение от kolorotur Посмотреть сообщение
Предоставьте пример, при котором это возможно.
Что-то не могу придумать.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.04.2019, 17:10
Лучший ответ Сообщение было отмечено Соколиный глаз как решение

Решение

Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Что-то не могу придумать.
Правильно, потому что такого примера нет.
Судите сами: в классе имеется метод со следующей сигнатурой:
C#
1
2
3
4
5
6
class FruitBasket
{
   public void Put(Fruit fruit)
   {
   }
}
О чем говорит эта сигнатура? О том, что метод Put может корректно обработать любой объект типа Fruit.
Полиморфизм и принцип подстановки Лисков позволяет передавать в этот метод объект любого типа, являющегося или наследующегося от Fruit:
C#
1
2
3
4
5
var basket = new FruitBasket();
basket.Put(new Apple()); // OK
basket.Put(new Orange()); // OK
basket.Put(new Pineapple()); // OK
basket.Put(new Banana()); // OK
До тех пор, пока типы передаваемых объектов наследуются от Fruit, существует ли в примере выше ситуация, при которой будет нарушена строгая типизация? Обратите внимание, что никаких интерфейсов нет.
Думаю, вы согласитесь, что такой ситуации нет.

Теперь добавляем интерфейс и реализуем его в классе:
C#
1
2
3
4
5
6
7
8
interface IBasket<in T>
{
   void Put(T item);
}
 
class FruitBasket : IBasket<Fruit> { ... }
 
IBasket<Fruit> basket = new FruitBasket();
Нужно ли после изменений как-то менять код добавления? Нет.
Будет ли он работать точно так же и по тем же принципам что и раньше? Да.

Ну а если мы можем передать в метод, принимающий Fruit, ссылку на объект типа Apple, то уж тем более мы можем передать эту ссылку в метод, принимающий Apple, верно?
Потому и работает контрвариантность: если конкретный тип принимает на вход ссылку на родительский класс, то он может принять на вход ссылку на любой класс, наследующийся от этого родительского.
Ну а если это всегда так, то почему бы не добавить немного удобства и не позволить делать соответствующие приведения?
C#
1
2
3
IBasket<Fruit> basket = new FruitBasket();
IBasket<Apple> appleBasket = basket;
appleBasket.Put(new Apple()); // ОК, потому что basket может принять Apple, а передать ананас вам все равно не позволит компилятор.
1
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
17.04.2019, 17:38  [ТС]
kolorotur, а если в basket не только яблоки лежат?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.04.2019, 17:58
Лучший ответ Сообщение было отмечено Соколиный глаз как решение

Решение

Цитата Сообщение от Соколиный глаз Посмотреть сообщение
а если в basket не только яблоки лежат?
Да и бог с ними — пусть лежат, вы ведь ничего не пытаетесь оттуда достать, а только положить.
Вот если бы пытались достать — была бы проблема, да. Именно поэтому контрвариантные интерфейсы запрещают иметь тип-параметр на выходящих позициях!
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.04.2019, 17:58
Помогаю со студенческими работами здесь

Как преобразовать число типа int в строку типа string без методов-конвертов на C#?
В общем, все что выше написано. Пишу в Visual Studio на C#. Преобразовать без конвертирования, например, дано int, дано string, и это число...

Ошибка при использовании IEnumerable<T>: Использование универсального типа IEnumerable требует аргумент типа 1
Доброго Вам времени суток. Помогите решить следующую задачку. На строке IEnumerable&lt;Device&gt; = deviceContext.Devices; возникает...

Использование byte[] как generic-типа
Подскажите правильное направление в решении такой проблемы. Есть некий класс public class DataQueue&lt;T&gt; : IDisposable where T:...

Как правильно реализовать проверку типа передаваемого аргумента в шаблонной функции?
Доброго времени суток, уважаемые форумчане! Пытаюсь реализовать проверку типа аргумента, передаваемого шаблонной функции. Использую...

Возврат объекта шаблонного типа от типа Type из специализации шаблона метода от того же типа
Доброго времени суток, пишу класс содержащий несколько std::set от разных типов, нужно сделать метод возвращающий указатель на нужное...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru