Есть ли вообще понятие таблицы виртуальных функций в шарпе? Допустим есть иерархия классов, в классе на вершине иерархии виртуальный метод, который переопределяется в child классах. Методы с середины иерархии с меткой override заносятся в таблицу виртуальных функций? Также интересует заносится ли метод из последнего класса в иерархии?
И наконец, читаю книгу "Clr via c#", до конца не могу понять, сказано, что для структур используется call для вызова функций, т. к. это значимый тип, но структуры также неявно наследуются от System.Object и могут оверрайдить методы, так вот, вопрос, для этих методов используется call или callvirt? Также интересует, когда используется call для вызова виртуальных функций и как работает таблица виртуальных функций для структур, т.к. методы оверрайдятся.
Заранее спасибо за ответы
Есть ли вообще понятие таблицы виртуальных функций в шарпе? Допустим есть иерархия классов, в классе на вершине иерархии виртуальный метод, который переопределяется в child классах. Методы с середины иерархии с меткой override заносятся в таблицу виртуальных функций?
Не столько "виртуальных", сколько просто таблица функций (методов). Каждый тип имеет таблицу методов, которая хранит указатели на дескрипторы всех методов этого класса, как виртуальных, так обычных. В таблицу каждого типа заносится указатель либо на реализацию в этом типе, если это собственный или переопределенный виртуальный метод, либо на одну из реализаций выше по иерархии, если он унаследован. Естественно, каждая реализация будет в какой-то таблице, иначе как ее можно было бы вызвать?
Информацию о структуре таблицы методов можно посмотреть здесь: .NET Framework Internals: How the CLR Creates Runtime Objects - хоть статья и старая, идеи в основном не изменились.
сказано, что для структур используется call для вызова функций, т. к. это значимый тип, но структуры также неявно наследуются от System.Object и могут оверрайдить методы, так вот, вопрос, для этих методов используется call или callvirt? Также интересует, когда используется call для вызова виртуальных функций и как работает таблица виртуальных функций для структур, т.к. методы оверрайдятся
call используется для вызова статического метода, либо для вызова метода экземпляра через раннее связывание (метод известен на этапе компиляции). Метод может быть как виртуальным, так и обычным, и принадлежать как структуре, так и классу. Но если вызвать виртуальный метод через call
, virtual dispatch на деле не происходит, т.е. вызов вырождается в невиртуальный.
callvirt используется для вызова методов экземпляра через позднее связывание (метод определяется реальным типом объекта во время выполнения). Метод может быть как виртуальным, так и обычным, и принадлежать как структуре, так и классу. Но для обычного метода позднее связывание, конечно, вырождается в ранее, так как выбирать CLR не из чего (у всех наследников реализация одна и та же).
На практике, компилятор C# генерирует callvirt
для вызовов всех виртуальных методов и вызовов обычных методов на классах (последнее связано, насколько я знаю, с лучшей диагностикой вызовов по null-ссылкам). call
он генерирует для вызовов статических методов и вызовов обычных методов на структурах.
Следует понимать, что тут много тонкостей, все из которых невозможно описать в рамках ответа. Например, метод, реализующий интерфейс, с точки зрения CLR будет всегда виртуальным, даже если мы об этом не просили, т.е. не пометили его virtual
в C#. Кроме того, чтобы callvirt
работал со структурами, используется специальный префикс constrained. Полную информацию о внутренней механике CLR и структуре IL-кода можно посмотреть в спецификации ECMA-335 Common Language Infrastructure.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
ПомогитеКак сделать проверку, передается ли в метод хоть какое то числовое значение?
Недавно начал курс по Web ,а для сборки задания нуженNet Core SDK 1
Скачал готовый шаблон сайта при подключении формы отправки на e-mail возникли проблемы вот код