Вы думаете, что это слишком сложно.
Содержит ли ссылка 'f' информацию о типе?
Нет.Это не обязательно.Это просто адрес начала памяти объекта Bar
, который был построен ранее. Этот объект содержит таблицу виртуальных методов (и, возможно, ссылку на связанный с ним Type
объект 1 , но здесь это не имеет значения).
Когда яВызовите f.Baz (), правильно ли я думаю, что отправка происходит через MethodTable Бара?
Да.
Это просто тот случай, когда компилятор C #использует анализ потока, чтобы выяснить, что происходит и предотвратить любые незаконные операции?
Анализ потока здесь сложен и совершенно не нужен.Компилятор разрешает именно те операции, которые разрешены для типа объявления f
- Foo
.Компилятор не заботится о фактическом (= динамическом) типе f
.
Не могли бы вы сказать, какое исходное объявление было получено из результирующего IL?
Зависит. объект не не имеет статического типа, поэтому «указывать свой статический тип во время выполнения» не имеет смысла.Декларации, с другой стороны, отличаются.Если переменная является формальным параметром метода, тогда, конечно, вы можете (во время выполнения) использовать отражение, чтобы определить тип объявления параметра метода.
Для локальных переменных, снова эта операция не имеет смысла.С другой стороны, IL сохраняет эту информацию (как метаданные?) Через .locals
, поэтому код может теоретически быть реверсивно спроектирован (Cecil и Reflector делают это), чтобы получитьстатический тип переменных.
1 Я предполагаю здесь, но это на самом деле невероятно .Если бы каждый объект содержал свою собственную ссылку на связанный объект Type
, это означало бы дополнительные издержки указателя.Кроме того, эта ссылка совершенно не нужна, поскольку объект может просто вызвать GetType
для получения своего типа.GetType
должен быть реализован только один раз для каждого класса (на самом деле это статический метод) и отправляется через обычную таблицу виртуальных функций.Таким образом, для каждого класса требуется только одна ссылка на Type
, в отличие от каждого объекта.