Я написал в блоге о том, как callvirt работает во время выполнения.
Во время компиляции аргумент инструкции callvirt
принимает конкретный MethodDef
или * 1007.* token, ссылающийся на вызываемый «базовый» метод (среди прочего, он определяет аргументы метода)
Во время выполнения, как часть инициализации типа, CLR определяет, какие методы переопределяют друг друга, иназначает слот в таблице MethodTable
vtable для каждого виртуального «базового» метода.Каждый тип затем заполняет этот слот указателем на то, какую фактическую реализацию метода следует использовать для виртуальных вызовов этого базового метода для экземпляров этого типа.Затем он используется для виртуального вызова, как описано в моем посте.