Несколько дополнительных мыслей.
Что видит CLR при выполнении этого кода
Как правильно заметили Джон и другие, мы не делаем различия между классами, только интерфейсами и делегатами. Так что в вашем примере CLR ничего не видит; этот код не компилируется. Если вы заставите его скомпилировать, вставив достаточное количество приведений, он завершится с ошибкой во время выполнения.
Теперь все еще разумно задать вопрос, как дисперсия работает за сценой, когда она работает. Ответ таков: причина, по которой мы ограничиваем это ссылочными аргументами типа, которые параметризуют интерфейс и типы делегатов, заключается в том, что ничего не происходит за кадром. Когда вы говорите
object x = "hello";
за кулисами происходит ссылка на строку, вставленную в переменную типа object без изменения . Биты, составляющие ссылку на строку, являются допустимыми битами для ссылки на объект, поэтому здесь ничего не должно происходить. CLR просто перестает думать об этих битах как о ссылке на строку и начинает думать о них как об объекте.
Когда вы говорите:
IEnumerator<string> e1 = whatever;
IEnumerator<object> e2 = e1;
То же самое. Ничего не произошло. Биты, которые ссылаются на перечислитель строк, совпадают с битами, которые ссылаются на перечислитель объекта. Когда вы выполняете каст, в игру вступает немного больше магии, скажем:
IEnumerator<string> e1 = whatever;
IEnumerator<object> e2 = (IEnumerator<object>)(object)e1;
Теперь CLR должен сгенерировать проверку того, что e1 действительно реализует этот интерфейс, и эта проверка должна быть умной для распознавания отклонений.
Но причина, по которой мы можем избавиться от вариантов интерфейсов, являющихся просто неоперативными преобразованиями, заключается в , потому что совместимость с обычными назначениями именно так Для чего вы собираетесь использовать e2?
object z = e2.Current;
Возвращает биты, которые являются ссылкой на строку. Мы уже установили, что они совместимы с объектом без изменений.
Почему это не было введено ранее? У нас были другие возможности и ограниченный бюджет.
В чем принципиальная выгода? Это преобразование из последовательности строки в последовательность объекта "просто работа".