Если кто-то разрабатывает интерфейс, подобный ILookup
(для простоты, предположим, что это просто ICheckIfContained
, поэтому тип значения элемента не имеет значения), какой будет идеальный тип дисперсии по отношению к первому параметр
Проверка того, содержит ли ICheckIfContained<Animal>
конкретный Cat
, будет естественной операцией и будет безопасна по типу при обычных правилах контравариантности.
Проверка, чтобы увидеть, содержит ли ICheckIfContained<Cat>
конкретный Animal
, не будет типобезопасным при нормальных правилах контравариантности, но будет естественным и четким (если рассматриваемый Animal
не является Cat
, правильное поведение было бы для ICheckIfContained
, чтобы сказать, что оно не содержит рассматриваемого животного).
Проверка того, содержит ли ICheckIfContained<Cat>
конкретный Dog
, не будет особенно полезной (ответ всегда будет «нет»), но ответ будет четко определен. Обратите внимание, что ответ в этом сценарии, в отличие от предыдущего, может быть определен статически.
Один из подходов состоит в том, чтобы ICheckIfContained
был не универсальным интерфейсом и просто принимал параметр типа Object
. Однако это может показаться неэффективным в тех случаях, когда список содержит только один тип структуры. С другой стороны, если это универсальный интерфейс, то компилятор не сможет разрешить его использование в ковариантном сценарии (передача параметра, объявленный тип которого является родительским для ожидаемого типа, так что переданный объект может может не соответствовать ожидаемому типу).
Есть ли хороший шаблон для получения эффективности обобщений в тех случаях, когда компилятор может подтвердить, что все имеют один и тот же тип, и в то же время разрешить поведение общего случая проверки наличия объекта родительского типа в коллекции дочерний тип?