В C # все привязано заранее, если вы не используете интерфейс Reflection.
Ранняя привязка просто означает, что целевой метод найден во время компиляции и создается код, который его вызовет. Независимо от того, виртуальный он или нет (это означает, что есть дополнительный шаг, чтобы найти его во время вызова, не имеет значения). Если метод не существует, компилятор не сможет скомпилировать код.
Поздняя привязка означает, что целевой метод просматривается во время выполнения. Часто для его поиска используется текстовое имя метода. Если метода нет, бац. Программа выйдет из строя или перейдет в некоторую схему обработки исключений во время выполнения.
Большинство языков сценариев используют позднее связывание, а скомпилированные языки используют раннее связывание.
C # (до версии 4) не связывает поздно; Однако они могут использовать для этого API отражения. Этот API компилируется в код, который ищет имена функций, копаясь в сборках во время выполнения. VB может выполнить позднее связывание, если параметр Option Strict отключен.
Связывание обычно влияет на производительность. Поскольку для позднего связывания требуется поиск во время выполнения, это обычно означает, что вызовы методов выполняются медленнее, чем вызовы методов раннего связывания.
Для нормальной функции компилятор может определить ее числовое расположение в памяти. Затем, когда функция вызывается, она может сгенерировать инструкцию для вызова функции по этому адресу.
Для объекта, у которого есть какие-либо виртуальные методы, компилятор сгенерирует v-таблицу. По сути, это массив, содержащий адреса виртуальных методов. Каждый объект, имеющий виртуальный метод, будет содержать скрытый член, сгенерированный компилятором, который является адресом v-таблицы. Когда вызывается виртуальная функция, компилятор определяет позицию соответствующего метода в v-таблице. Затем он сгенерирует код для просмотра v-таблицы объектов и вызова виртуального метода в этой позиции.
Итак, для виртуальной функции выполняется поиск. Это сильно оптимизировано, поэтому во время выполнения это произойдет очень быстро.
Ранняя граница
- Компилятор может определить, где будет находиться вызываемая функция во время компиляции.
- Компилятор может гарантировать на раннем этапе (до запуска кода любой из программ), что функция будет существовать и быть вызываемой во время выполнения.
- Компилятор гарантирует, что функция принимает правильное количество аргументов и что они имеют правильный тип. Он также проверяет, что возвращаемое значение имеет правильный тип.
Поздняя привязка
- Поиск займет больше времени, потому что это не простой расчет смещения, обычно требуется сравнение текста.
- Целевая функция может не существовать.
- Целевая функция может не принимать переданные ей аргументы и может иметь возвращаемое значение неправильного типа.
- В некоторых реализациях целевой метод может фактически изменяться во время выполнения. Таким образом, поиск может выполнять другую функцию. Я думаю, что это происходит на языке Ruby, вы можете определить новый метод для объекта во время работы программы. Позднее связывание позволяет вызовам функций начинать вызывать новое переопределение для метода вместо вызова существующего базового метода.
C # 3 использует раннее связывание.
C # 4 добавляет позднее связывание с
dynamic
ключевым словом. См . Запись в блоге Криса Берроу по этому поводу.Что касается виртуальных и невиртуальных методов, это другой вопрос. Если я позвоню
string.ToString()
, код C # будет привязан к виртуальномуobject.ToString()
методу. Код вызывающей стороны не меняется в зависимости от типа объекта. Скорее, виртуальные методы вызываются через таблицу указателей функций. Экземпляр объекта относится к таблице объекта, указывающей на егоToString()
метод. У экземпляра строки есть таблица виртуальных методов, указывающая на этотToString()
метод. Да, это полиморфизм. но это еще не поздно.источник
В большинстве случаев раннее связывание - это то, что мы делаем ежедневно. Например, если у нас есть
Employee
класс, доступный во время компиляции, мы просто создаем экземпляр этого класса и вызываем любые члены экземпляра. Это раннее связывание.//Early Binding **Employee** employeeObject = new **Employee**(); employeeObject.CalculateSalary();
С другой стороны, если у вас нет знаний о классе во время компиляции, то единственный способ - позднее выполнить привязку с помощью отражения. Я наткнулся на отличное видео, объясняющее эти концепции - вот ссылка .
источник
Это очень старый пост, но я хотел добавить к нему больше информации. Позднее связывание используется, когда вы не хотите создавать экземпляр объекта во время компиляции. В
C#
использованииActivator
для вызова привязки объекта во время выполнения.источник
Раннее связывание
Само название говорит о том, что компилятор знает, что это за объект, какие методы и свойства он содержит. Как только вы объявите объект, .NET Intellisense заполнит его методы и свойства при нажатии кнопки с точкой.
Общие примеры:
ComboBox cboItems;
ListBox lstItems; В приведенных выше примерах, если мы введем cboItem и поставим точку, за которой следует, он автоматически заполнит все методы, события и свойства поля со списком, потому что компилятор уже знает, что это поле со списком.
Позднее связывание
Само название описывает, что компилятор не знает, что это за объект, какие методы и свойства он содержит. Вы должны объявить его как объект, позже вам нужно будет получить тип объекта, методы, которые в нем хранятся. Все будет известно во время выполнения.
Общие примеры:
Object objItems;
objItems = CreateObject («Имя DLL или сборки»); Здесь во время компиляции тип objItems не определяется. Мы создаем объект dll и назначаем его objItems, поэтому все определяется во время выполнения.
Раннее связывание против позднего связывания
Теперь перейдем к картине ...
Приложение будет работать быстрее при раннем связывании, поскольку здесь не выполняется упаковка или распаковка.
Проще написать код в ранней привязке, так как intellisense будет заполнен автоматически
Минимальные ошибки при раннем связывании, поскольку синтаксис проверяется во время самой компиляции.
Позднее связывание будет поддерживаться во всех версиях, поскольку все решается во время выполнения.
Минимальное влияние кода на будущие улучшения, если используется Late Binding.
Производительность будет кодом в ранней привязке. У обоих есть достоинства и недостатки, и разработчик должен выбрать подходящую привязку на основе сценария.
источник
Проще говоря, раннее связывание происходит во время компиляции, и компилятор знает о типе и всех его членах, а позднее связывание происходит во время выполнения, компилятор ничего не знает о типе и его членах. Я наткнулся на отличное видео на YouTube, в котором объясняются эти концепции.
http://www.youtube.com/watch?v=s0eIgl5iqqQ&list=PLAC325451207E3105&index=55&feature=plpp_video
http://www.youtube.com/playlist?list=PLAC325451207E3105
источник
Эта статья представляет собой руководство по созданию компонента .net, использованию его в проекте Vb6 во время выполнения с использованием позднего связывания, присоединения его событий и получения обратного вызова.
http://www.codeproject.com/KB/cs/csapivb6callback2.aspx
Эта статья представляет собой руководство по созданию компонента .NET и его использованию в проекте VB6. Есть много примеров по этой проблеме, так зачем я написал новый? По моему скромному мнению, в других статьях недостающей частью является прикрепление своего события во время выполнения. Итак, в этой статье мы создадим компонент .NET, отметим его как видимый компонент COM, будем использовать его во время выполнения в VB6 и присоединим к его событиям.
https://www.codeproject.com/Articles/37127/Internet-Explorer-Late-Binding-Automation
Большинству разработчиков часто требуется автоматизация Internet Explorer, что в основном означает открытие браузера, заполнение некоторых форм и программную публикацию данных.
Наиболее распространенный подход - использовать shdocvw.dll (элемент управления Microsoft Web Browser) и Mshtml.dll (компонент анализа и рендеринга HTML) или Microsoft.Mshtml.dll, который на самом деле является оболочкой .NET для Mshtml.dll. Вы можете получить дополнительную информацию об Internet Explorer - о браузере здесь.
Если вы выберете вышеуказанный метод и библиотеки DLL, давайте посмотрим на некоторые проблемы, с которыми вам, возможно, придется столкнуться:
Вы должны распространять эти библиотеки DLL, потому что ваш проект будет зависеть от этих библиотек DLL, и это серьезная проблема, если вы не можете правильно их развернуть. Просто погуглите о проблемах с распространением shdocvw и mshtml.dll, и вы поймете, о чем я говорю. Вам необходимо развернуть Microsoft.mshtml.dll размером 8 МБ, потому что эта DLL не является частью платформы .NET. В этом случае нам нужно использовать технику позднего связывания. Написание собственных оболочек для вышеупомянутых DLL. И, конечно же, мы сделаем это, потому что это более полезно, чем использование этих DLL. Например, нам не нужно проверять, завершена ли операция загрузки документа, потому что IEHelper сделает это за нас.
источник