Все рано связывается в C #, если вы не пройдете через интерфейс Reflection.
Раннее связывание означает, что целевой метод найден во время компиляции, и создан код, который будет вызывать это. Является ли он виртуальным или нет (то есть, есть дополнительный шаг, чтобы найти его во время разговора, не имеет значения). Если метод не существует, компилятор не сможет скомпилировать код.
Поздняя граница означает, что целевой метод ищется во время выполнения. Часто текстовое имя метода используется для его поиска. Если метод не существует, взрыв. Во время выполнения программа завершится сбоем или перейдет к какой-либо схеме обработки исключений.
Большинство языков сценариев используют позднюю привязку, а скомпилированные языки используют раннюю привязку.
C # (до версии 4) не выполняет позднюю привязку; однако они могут использовать API отражения для этого. Этот API компилируется в код, который ищет имена функций, просматривая сборки во время выполнения. VB может выполнить позднее связывание, если Option Strict выключен.
Связывание обычно влияет на производительность. Поскольку позднее связывание требует поиска во время выполнения, обычно это означает, что вызовы методов медленнее, чем вызовы методов с ранним связыванием.
Для нормальной функции компилятор может определить ее числовое местоположение в памяти. Затем он при вызове функции может генерировать инструкцию для вызова функции по этому адресу.
Для объекта, у которого есть какие-либо виртуальные методы, компилятор сгенерирует v-таблицу. По сути, это массив, содержащий адреса виртуальных методов. Каждый объект, имеющий виртуальный метод, будет содержать скрытый элемент, сгенерированный компилятором, который является адресом v-таблицы. Когда вызывается виртуальная функция, компилятор определяет, какова позиция соответствующего метода в v-таблице. Затем он сгенерирует код для просмотра v-таблицы объектов и вызова виртуального метода в этой позиции.
Итак, поиск для виртуальной функции происходит. Это сильно оптимизировано, поэтому это будет происходить очень быстро во время выполнения.
Ранняя оценка
- Компилятор может определить, где будет вызвана функция во время компиляции.
- Компилятор может рано (до запуска кода любой программы) гарантировать, что функция будет существовать и будет вызываться во время выполнения.
- Компилятор гарантирует, что функция принимает правильное количество аргументов и что они имеют правильный тип. Он также проверяет, что возвращаемое значение имеет правильный тип.
Поздний переплет
- Поиск займет больше времени, потому что это не простое вычисление смещения, обычно необходимо выполнить сравнение текста.
- Целевая функция может не существовать.
- Целевая функция может не принимать переданные ей аргументы и может иметь возвращаемое значение неправильного типа.
- В некоторых реализациях целевой метод может фактически меняться во время выполнения. Таким образом, поиск может выполнять другую функцию. Я думаю, что это происходит на языке Ruby, вы можете определить новый метод для объекта во время работы программы. Позднее связывание позволяет вызовам функций начинать вызывать новое переопределение для метода вместо вызова существующего базового метода.