Почему С#/CLR не поддерживает метод переопределения co/contra-variance?
Существует немало вопросов и ответов о том, как взломать ограничение С#, не позволяющее использовать типы возвращаемых методов (и аргументов) для совместимых типов при переопределении, но why существует это ограничение, либо в компиляторе С#, либо в CLR? Как я вижу, нет ничего, что могло бы сломаться, если бы разрешалось совпадение/противоречие, так почему же это объясняется?
Аналогичный вопрос можно задать для расширения параметров доступа - например, переопределение защищенного внутреннего метода с помощью общедоступного метода (что-то, что поддерживает Java, IIRC)
Ответы
Ответ 1
Эрик Липперт уже ответил так лучше, чем мог.
Посмотрите его серию на Ковариация и контравариантность в С#
и
Как расширенная ковариация С# 4.0 и Contra-variance?
EDIT: Эрик указал, что он не говорит о конвариантности типа возврата, но я решил оставить ссылку в этом ответе, потому что это классная серия статей, и кто-то может найти ее полезной, если смотреть на эту тему.
Эта функция была запрошена, и почти 5 лет назад Microsoft ответила "Спасибо за регистрацию этого файла. Мы много слышим этот запрос. Мы рассмотрим его для следующего выпуска".
И теперь я приведу Jon Skeet, потому что это не будет правильным ответом на StackOverflow без ответа Джона Скита. Ковариационные и void возвращаемые типы
Я сильно подозреваю, что ответ заключается в реализации CLR а не в какой-либо глубокой семантической причина - CLR, вероятно, необходимо знать, будет ли там быть возвращаемым значением, чтобы сделать соответствующие вещи со стеком. Тем не менее, кажется, немного жаль, в условия элегантности. Я не могу сказать, что я когда-либо ощущала потребность в этом в реальном жизни, и было бы достаточно легко для подделки (для четырех параметров) в .NET 3.5, просто записав конвертер от Func<X>
до Action<X>
, Func<X,Y>
до Action<X,Y>
и т.д. Немного хотя:)
Ответ 2
Этот ответ не говорит о С#, но это помогло мне лучше понять проблемы и, возможно, это поможет другим: Почему нет параметра contra-variance для переопределения?
Ответ 3
Швы, вводящие ковариацию возвращаемого значения, не имеют существенного недостатка, как использовались Java и С++. Тем не менее, существует реальная путаница, связанная с введением противоположной дисперсии формального параметра. Я думаю, что этот ответ fooobar.com/questions/205255/... в С++ также применим для С#.
Ответ 4
Это так, вам просто нужно ждать VS2010/.Net 4.0.
Ответ 5
Чтобы расширить ответ на Joel, CLR поддерживает ограниченную дисперсию в течение длительного времени, но компилятор С# не использует их до 4.0 с новыми модификаторами "in" и "out" на общих интерфейсах и делегатах. Причины сложны, и я попытаюсь объяснить, но это не так просто, как кажется.
Переведите "защищенный внутренний" метод в "общедоступный" метод; вы можете сделать это с помощью метода hiding:
public new void Foo(...) { base.Foo(...); }
(до тех пор, пока аргументы и т.д. также являются общедоступными) - любое использование?