Ну, здесь два вопроса.Во-первых, может ли компилятор всегда делать это?Во-вторых, должно это (если это возможно)?
По первому вопросу я перейду к Эрику Липперту, который сделал этот комментарий, когда я поднял именно эту проблему во 2-м издании.C # в глубине:
Мне не ясно, что мы разумно могли бы, даже если бы захотели.Мы можем легко придумать ситуации, которые требуют дорогостоящего глобального анализа всех интерфейсов в программе, чтобы обработать отклонения, и мы можем легко придумать ситуации, когда это либо <in T, out U>
, либо <out T, in U>
, и нет способа выбрать между ними,И с плохой производительностью, и с неоднозначными случаями это маловероятная особенность.
(Надеюсь, Эрик не возражает против того, чтобы я цитировал это дословно; ранее он был очень хорош в обмене такими идеями, поэтому я продолжупрошлая форма:)
С другой стороны, я подозреваю, что все еще есть случаи, когда можно сделать вывод без двусмысленности, поэтому второй пункт все еще актуален ...
Я не думаю, что это должно быть автоматическим, даже если компилятор может однозначно знать, что он действителен только одним способом.Хотя расширение интерфейса всегда в некоторой степени является серьезным изменением, обычно это не так, если вы единственный, кто его реализует.Однако, если люди полагаются на ваш интерфейс как вариант, вы, возможно, не сможете в состоянии добавлять методы к нему, не нарушая клиентов ... даже если они просто звонящие, а не разработчики.Методы, которые вы добавляете, могут изменить ранее ковариантный интерфейс, чтобы он стал инвариантным, и в этот момент вы нарушаете все вызывающие, которые пытаются использовать его ковариантно.
В принципе, я думаю, что это нормально, требовать, чтобы это было явным - этопроектное решение, которое вы должны принимать осознанно, а не просто случайно получить ковариацию / контравариантность, не задумываясь об этом.