Ответ 1
Я рекомендую читать Generics в С#, Java и С++: Беседа с Андерсом Хейльсбергом.
Qn 1. Как обобщить обобщения JIT-компилятор?
Из интервью:
Андерс Хейлсберг: [...] В CLR [Common Language Runtime] когда вы компилируете List или любой другой общий тип, он компилируется до IL [Промежуточный язык] и метаданные как и любой нормальный тип. ИЛ и метаданные содержат дополнительные информация, которая знает там тип параметр, конечно, но в принцип, обобщенный тип компиляции просто так, как любой другой тип компиляции. Во время выполнения, когда ваш приложение делает свою первую ссылку к списку, система смотрит на если кто-то уже попросил
List<int>
. Если нет, он загружается в JIT IL и метаданные дляList<T>
и аргумент типа int. JITER, в процессе JITing IL, также заменяет параметр типа.[...]
Теперь, что мы делаем тогда для всех типов экземпляры, которые являются значениями типы, такие как
List<int>, List<long>, List<double>, List<float>
- мы создаем уникальная копия исполняемого файла код. Таким образом,List<int>
получает свой собственный код.List<long>
получает свой собственный код.List<float>
получает свой собственный код. Для всех ссылочные типы, которыми мы разделяем код, потому что они репрезентативно идентичны. Это просто указатели.
Qn 2. Дело в том, что новые типовые типы могут быть созданы во время выполнения, используя отражение. Что может, конечно, повлиять общие ограничения. Который уже прошел семантический парсер. Может кто-нибудь объяснить, как это обрабатываются?
По сути, IL сохраняет высокоуровневое представление общих типов, что позволяет CLR проверять ограничения на "динамически построенные" общие типы во время выполнения так же, как компилятор С# может делать для "статически построенных" типов в источнике С# -код во время компиляции.
Вот еще один фрагмент (акцент мой):
Андерс Хейлсберг: [...] С ограничением вы можете динамическая проверка вашего кода и проверить его во время компиляции или время загрузки.. Когда вы говорите, что K должен реализовать IComparable, пару всякое случается. При любом значении типа K, теперь вы можете напрямую получить доступ к интерфейсные методы без литья, потому что семантически в программе он гарантировал, что он будет реализовывать этот интерфейс. Всякий раз, когда вы пытаетесь создать экземпляр этого типа, компилятор проверяет, что любой тип вы даете в качестве аргумента K аргументы IComparable, иначе вы получите компиляцию временная ошибка. Или, если вы делаете это с вы получаете исключение.
Брюс Эккел: Вы сказали, что компилятор и время выполнения.
Андерс Хейлсберг: Проверка компилятора это, но вы также можете сделать это на времени выполнения с отражением, а затем система проверяет его. Как я уже говорил, все, что вы можете сделать во время компиляции, вы также можете выполнять во время работы с отражение.