Ligação antecipada e tardia

Eu estou tentando obter minha cabeça quando binding antecipada / tardia ocorre em c #.

Métodos não virtuais são sempre vinculados antecipadamente. Os methods virtuais são sempre vinculados tardiamente: o compilador insere código extra para resolver o método real ao qual se ligar no momento da execução e verifica a segurança do tipo. Então, o polymorphism de subtipo usa binding tardia.

Chamar methods usando reflection é um exemplo de binding tardia. Nós escrevemos o código para conseguir isso, ao contrário do compilador. (Por exemplo, chamando componentes COM.)

VB.NET suporta binding tardia implícita quando Option Strict está desativado. Um object está atrasado quando é atribuído a uma variável declarada como sendo do tipo Object. O compilador VB insere código para vincular o método certo no tempo de execução e para capturar chamadas inválidas. C # não suporta este recurso.

Estou indo na direção certa?

Que tal chamar delegates e chamar um método através de uma referência de interface? Isso é binding antecipada ou tardia?

Tudo é inicializado em C # a menos que você passe pela interface Reflection.

Limite antecipado significa apenas que o método de destino é encontrado em tempo de compilation e o código é criado para chamar isso. Se o seu virtual ou não (ou seja, há um passo extra para encontrá-lo no tempo de chamada é irrelevante). Se o método não existir, o compilador não compilará o código.

Atrasado tardio significa que o método de destino é consultado em tempo de execução. Geralmente, o nome textual do método é usado para procurá-lo. Se o método não está lá, bang. O programa irá travar ou entrar em algum esquema de exception handling no tempo de execução.

A maioria das linguagens de script usa vinculação tardia e as linguagens compiladas usam vinculação antecipada.

C # (antes da versão 4) não liga tardiamente; eles podem, no entanto, usar a API de reflection para fazer isso. Essa API compila para codificar que procura nomes de function cavando através de assemblies em tempo de execução. O VB pode atrasar se o Option Strict for desativado.

Ligação geralmente tem um efeito no desempenho. Como binding tardia requer pesquisas em tempo de execução, geralmente significa que as chamadas de método são mais lentas do que as chamadas de método de binding iniciais.


Para uma function normal, o compilador pode calcular a localização numérica dele na memory. Então, quando a function é chamada, pode gerar uma instrução para chamar a function nesse endereço.

Para um object que tenha qualquer método virtual, o compilador gerará uma v-table. Essencialmente, é uma matriz que contém os endereços dos methods virtuais. Todo object que possui um método virtual conterá um membro oculto gerado pelo compilador que é o endereço da tabela-v. Quando uma function virtual é chamada, o compilador calculará qual é a posição do método apropriado na tabela-v. Em seguida, ele gerará o código para procurar na tabela v de objects e chamar o método virtual nessa posição.

Portanto, há uma pesquisa que ocorre para a function virtual. Isso é altamente otimizado, por isso acontecerá muito rapidamente em tempo de execução.

Limite antecipado

  • O compilador pode descobrir onde a function chamada estará em tempo de compilation.
  • O compilador pode garantir antecipadamente (antes que qualquer código do programa seja executado) que a function existirá e possa ser chamada no tempo de execução.
  • O compilador garante que a function receba o número correto de argumentos e que eles sejam do tipo correto. Ele também verifica se o valor de retorno é do tipo correto.

Ligação tardia

  • A pesquisa levará mais tempo porque não é um cálculo de deslocamento simples, geralmente há comparações de texto a serem feitas.
  • A function de destino pode não existir.
  • A function de destino pode não aceitar os argumentos passados ​​para ela e pode ter um valor de retorno do tipo errado.
  • Com algumas implementações, o método de destino pode realmente mudar em tempo de execução. Assim, a pesquisa pode executar uma function diferente. Eu acho que isso acontece na linguagem Ruby, você pode definir um novo método em um object enquanto o programa está sendo executado. Ligação tardia permite que chamadas de function iniciem a chamada de uma nova substituição para um método em vez de chamar o método base existente.

C # 3 usa binding inicial.

C # 4 adiciona binding tardia com a palavra-chave dynamic . Veja a input do blog de Chris Burrow no assunto para detalhes.

Quanto aos methods virtuais versus não virtuais, esse é um problema diferente. Se eu chamar string.ToString() , o código C # é ligado ao método virtual object.ToString() . O código do chamador não muda com base no tipo do object. Em vez disso, os methods virtuais são chamados por meio de uma tabela de pointers de function. Uma instância de object refere-se à tabela do object apontando para o método ToString() . Uma instância de string tem sua tabela de método virtual apontando para seu método ToString() . Sim, isso é polymorphism. mas não é binding tardia.

Na maioria dos casos, a vinculação antecipada é o que fazemos diariamente. Por exemplo, se tivermos uma class Employee disponível em tempo de compilation, simplesmente criamos a instância dessa class e invocamos todos os membros da instância. Isso é binding antecipada.

 //Early Binding **Employee** employeeObject = new **Employee**(); employeeObject.CalculateSalary(); 

Por outro lado, se você não tiver o conhecimento da class em tempo de compilation, a única maneira é vincular tarde usando a reflection. Eu me deparei com um excelente vídeo explicando esses conceitos – aqui está o link .

É um post muito antigo, mas queria adicionar mais informações a ele. Ligação tardia é usada quando você não deseja instanciar o object em tempo de compilation. Em C# você usa o Activator para chamar o object bind em tempo de execução.

Vinculação antecipada

O próprio nome descreve que o compilador sabe que tipo de object é, quais são todos os methods e propriedades que ele contém. Assim que você declarar o object, o .NET Intellisense preencherá seus methods e propriedades ao clicar no botão de ponto.

Exemplos comuns:

CboItems ComboBox;

ListBox lstItems; Nos exemplos acima, se digitarmos cboItem e colocar um ponto seguido por, ele preencherá automaticamente todos os methods, events e propriedades de uma checkbox de combinação, porque o compilador já sabe que é uma checkbox de combinação.

Vinculação tardia

O próprio nome descreve que o compilador não sabe que tipo de object é, quais são todos os methods e propriedades que ele contém. Você tem que declará-lo como um object, depois você precisa obter o tipo do object, methods que são armazenados nele. Tudo será conhecido no tempo de execução.

Exemplos comuns:

Objetos de object;

objItems = CreateObject (“DLL ou nome do assembly”); Aqui durante o tempo de compilation, o tipo de objItems não é determinado. Estamos criando um object de uma dll e atribuindo-o aos objItems, então tudo é determinado no tempo de execução.

Vinculação antecipada versus vinculação tardia

Agora entrando na foto …

O aplicativo será executado mais rapidamente no Early binding, já que nenhum boxe ou unboxing é feito aqui.

Mais fácil de escrever o código no Early binding, já que o intellisense será automaticamente preenchido

Erros mínimos na binding antecipada, uma vez que a syntax é verificada durante o próprio tempo de compilation.

A binding tardia suportaria todos os tipos de versões, já que tudo é decidido no tempo de execução.

Minimal Impacto do código em aprimoramentos futuros, se a vinculação tardia for usada.

O desempenho será código na binding inicial. Ambos têm méritos e deméritos, é a decisão do desenvolvedor de escolher a binding apropriada com base no cenário.

Em termos muito simples, a vinculação antecipada acontece em tempo de compilation e o compilador tem o conhecimento sobre o tipo e todos os seus membros, e a vinculação tardia ocorre em tempo de execução, o compilador não sabe nada sobre o tipo e seus membros. Eu me deparei com um excelente vídeo no youtube, que explica esses conceitos.

http://www.youtube.com/watch?v=s0eIgl5iqqQ&list=PLAC325451207E3105&index=55&feature=plpp_video

http://www.youtube.com/playlist?list=PLAC325451207E3105

Este artigo é um guia para criar um componente .net, usando-o em um projeto Vb6 em tempo de execução usando binding tardia, anexando os events e obtendo um retorno de chamada.

http://www.codeproject.com/KB/cs/csapivb6callback2.aspx

Este artigo é um guia para criar um componente .NET e usá-lo em um projeto VB6. Existem muitas amostras sobre esse problema, então por que escrevi uma nova? Na minha humilde opinião, em outros artigos, a parte que falta é append seu evento em tempo de execução. Então, neste artigo, vamos construir um componente .NET, marcá-lo como um componente visível COM, usá-lo em tempo de execução no VB6 e append a seus events.

https://www.codeproject.com/Articles/37127/Internet-Explorer-Late-Binding-Automation

A maioria dos desenvolvedores geralmente precisa da automação do Internet Explorer, o que basicamente significa abrir um navegador, preencher alguns formulários e postar dados programaticamente.

A abordagem mais comum é usar shdocvw.dll (o controle do Microsoft Web Browser) e Mshtml.dll (o componente de processamento e processamento de HTML) ou o Microsoft.Mshtml.dll, que na verdade é um wrapper do .NET para Mshtml.dll. Você pode obter mais informações sobre o Internet Explorer – Sobre o navegador aqui.

Se você escolher o método acima e as DLLs, vamos ver alguns dos problemas que você pode ter que lidar:

Você tem que distribuir essas DLLs porque seu projeto seria dependente para essas DLLs, e isso é um problema sério se você não pode implantá-las corretamente. Basta fazer alguns pesquisando sobre shdocvw e mshtml.dll distribuindo problemas, e você verá o que estou falando. Você precisa implantar um Microsoft.mshtml.dll de 8 MB porque essa DLL não faz parte da estrutura .NET. Nesse caso, o que precisamos fazer é usar uma técnica de binding tardia. Escrevendo nossos próprios wrappers para as DLLs acima mencionadas. E, claro, faremos isso, pois é mais útil do que usar essas DLLs. Por exemplo, não precisaremos verificar se a operação de download de documentos está completa porque o IEHelper fará isso por nós.