web-dev-qa-db-fra.com

Reliure précoce et tardive

J'essaie de comprendre quand une liaison précoce/tardive se produit en C #.

Les méthodes non virtuelles sont toujours liées tôt. Les méthodes virtuelles sont toujours liées tardivement: le compilateur insère du code supplémentaire pour résoudre la méthode à laquelle se lier au moment de l'exécution et vérifie la sécurité du type. Le polymorphisme de sous-type utilise donc une liaison tardive.

Les méthodes d'appel utilisant la réflexion sont un exemple de liaison tardive. Nous écrivons le code pour y parvenir par opposition au compilateur. (Par exemple, appeler des composants COM.)

VB.NET prend en charge la liaison tardive implicite lorsque Option Strict est désactivé. Un objet est lié tardivement lorsqu'il est affecté à une variable déclarée de type Object. Le compilateur VB insère du code pour se lier à la bonne méthode au moment de l'exécution et pour intercepter les appels non valides. C # ne prend pas en charge cette fonctionnalité.

Suis-je dans la bonne direction?

Qu'en est-il d'appeler des délégués et d'appeler une méthode via une référence d'interface? S'agit-il d'une liaison anticipée ou tardive?

77
Josh

Tout est lié tôt en C #, sauf si vous passez par l'interface de réflexion.

Une liaison anticipée signifie simplement que la méthode cible est trouvée au moment de la compilation et qu'un code est créé qui l'appellera. Que ce soit virtuel ou non (ce qui signifie qu'il y a une étape supplémentaire pour le trouver au moment de l'appel n'a pas d'importance). Si la méthode n'existe pas, le compilateur ne parviendra pas à compiler le code.

La liaison tardive signifie que la méthode cible est recherchée au moment de l'exécution. Souvent, le nom textuel de la méthode est utilisé pour la rechercher. Si la méthode n'est pas là, bang. Le programme plantera ou entrera dans un schéma de gestion des exceptions au moment de l'exécution.

La plupart des langages de script utilisent une liaison tardive et les langages compilés utilisent une liaison précoce.

C # (avant la version 4) ne se lie pas tardivement; ils peuvent cependant utiliser l'API de réflexion pour le faire. Cette API se compile en code qui recherche les noms de fonction en fouillant dans les assemblys au moment de l'exécution. VB peut se lier tardivement si Option Strict est désactivé.

La liaison a généralement un effet sur les performances. Étant donné que la liaison tardive nécessite des recherches lors de l'exécution, cela signifie généralement que les appels de méthode sont plus lents que les appels de méthode liés tôt.


Pour une fonction normale, le compilateur peut déterminer son emplacement numérique en mémoire. Ensuite, lorsque la fonction est appelée, elle peut générer une instruction pour appeler la fonction à cette adresse.

Pour un objet qui a des méthodes virtuelles, le compilateur générera une v-table. Il s'agit essentiellement d'un tableau contenant les adresses des méthodes virtuelles. Chaque objet qui a une méthode virtuelle contiendra un membre caché généré par le compilateur qui est l'adresse de la v-table. Lorsqu'une fonction virtuelle est appelée, le compilateur déterminera quelle est la position de la méthode appropriée dans la v-table. Il générera ensuite du code pour rechercher dans la table d'objets v et appellera la méthode virtuelle à cette position.

Il existe donc une recherche qui se produit pour la fonction virtuelle. Ceci est fortement optimisé, donc cela se produira très rapidement au moment de l'exécution.

lié tôt

  • Le compilateur peut déterminer où sera la fonction appelée au moment de la compilation.
  • Le compilateur peut garantir tôt (avant l'exécution du code du programme) que la fonction existera et pourra être appelée au moment de l'exécution.
  • Le compilateur garantit que la fonction prend le bon nombre d'arguments et qu'ils sont du type correct. Il vérifie également que la valeur de retour est du type correct.

liaison tardive

  • La recherche prendra plus de temps car ce n'est pas un simple calcul de décalage, il y a généralement des comparaisons de texte à faire.
  • La fonction cible peut ne pas exister.
  • La fonction cible peut ne pas accepter les arguments qui lui sont passés et peut avoir une valeur de retour du mauvais type.
  • Avec certaines implémentations, la méthode cible peut en fait changer au moment de l'exécution. Ainsi, la recherche peut exécuter une fonction différente. Je pense que cela se produit dans le langage Ruby, vous pouvez définir une nouvelle méthode sur un objet pendant que le programme est en cours d'exécution. La liaison tardive permet aux appels de fonction de commencer à appeler un nouveau remplacement pour une méthode au lieu de appeler la méthode de base existante.
97
Scott Langham

C # 3 utilise une liaison anticipée.

C # 4 ajoute une liaison tardive avec le mot clé dynamic. Voir entrée du blog de Chris Burrow sur le sujet pour plus de détails.

En ce qui concerne les méthodes virtuelles et non virtuelles, c'est un problème différent. Si j'appelle string.ToString(), le code C # est lié à la méthode virtuelle object.ToString(). Le code de l'appelant ne change pas en fonction du type de l'objet. Les méthodes virtuelles sont plutôt appelées via une table de pointeurs de fonction. Une instance d'objet fait référence à la table d'objet pointant vers sa méthode ToString(). Une instance de chaîne a sa table de méthode virtuelle pointant vers sa méthode ToString(). Oui, c'est du polymorphisme. mais ce n'est pas une liaison tardive.

17
Joe Erickson

Dans la plupart des cas, la liaison anticipée est ce que nous faisons quotidiennement. Par exemple, si nous avons une classe Employee disponible au moment de la compilation, nous créons simplement l'instance de cette classe et invoquons les membres de l'instance. Il s'agit d'une liaison anticipée.

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

D'un autre côté, si vous n'avez pas la connaissance de la classe au moment de la compilation, alors le seul moyen est de lier tardivement en utilisant la réflexion. Je suis tombé sur une excellente vidéo expliquant ces concepts - voici le lien .

5
Prasad

Reliure précoce

Le nom lui-même décrit que le compilateur sait de quel type d'objet il s'agit, quelles sont toutes les méthodes et propriétés qu'il contient. Dès que vous avez déclaré l'objet, .NET Intellisense remplira ses méthodes et propriétés en cliquant sur le bouton point.

Exemples courants:

ComboBox cboItems;

ListBox lstItems; Dans les exemples ci-dessus, si nous tapons le cboItem et plaçons un point suivi par, il remplira automatiquement toutes les méthodes, événements et propriétés d'une zone de liste déroulante, car le compilateur sait déjà qu'il s'agit d'une zone de liste déroulante.

Reliure tardive

Le nom lui-même décrit que le compilateur ne sait pas de quel type d'objet il s'agit, quelles sont toutes les méthodes et propriétés qu'il contient. Vous devez le déclarer en tant qu'objet, plus tard, vous devez obtenir le type de l'objet, les méthodes qui y sont stockées. Tout sera connu au moment de l'exécution.

Exemples courants:

ObjItems d'objet;

objItems = CreateObject ("DLL ou nom d'assembly"); Ici, lors de la compilation, le type d'objItems n'est pas déterminé. Nous créons un objet d'une DLL et l'affectons aux objets, donc tout est déterminé au moment de l'exécution.

Liaison précoce vs liaison tardive

Entrant maintenant dans l'image…

L'application s'exécutera plus rapidement dans la liaison anticipée, car aucune boxe ou unboxing n'est effectuée ici.

Plus facile à écrire le code dans la liaison anticipée, car l'intellisense sera automatiquement rempli

Erreurs minimales dans la liaison anticipée, car la syntaxe est vérifiée pendant le temps de compilation lui-même.

La liaison tardive prend en charge toutes sortes de versions, car tout est décidé au moment de l'exécution.

Impact minimal du code dans les améliorations futures, si une liaison tardive est utilisée.

Les performances seront codées en liaison anticipée. Les deux ont des avantages et des inconvénients, c'est la décision du développeur de choisir la liaison appropriée en fonction du scénario.

3
RajGanesh

C'est un très vieux poste mais je voulais y ajouter plus d'informations. La liaison tardive est utilisée lorsque vous ne souhaitez pas instancier un objet au moment de la compilation. Dans C# vous utilisez Activator pour appeler l'objet bind lors de l'exécution.

3
Kumar Nitesh

En termes très simples, la liaison précoce se produit au moment de la compilation et le compilateur a la connaissance du type et de tous ses membres, et la liaison tardive se produit au moment de l'exécution, le compilateur ne sait rien du type et de ses membres. J'ai rencontré une excellente vidéo sur youtube qui explique ces concepts.

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

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

2
Suresh

Cet article est un guide pour créer un composant .net, l'utiliser dans un projet Vb6 lors de l'exécution en utilisant une liaison tardive, attacher ses événements et obtenir un rappel.

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

Cet article est un guide pour créer un composant .NET et l'utiliser dans un projet VB6. Il existe de nombreux exemples sur ce problème, alors pourquoi en ai-je rédigé un nouveau? À mon humble avis, dans d'autres articles, la partie manquante est d'attacher son événement lors de l'exécution. Ainsi, dans cet article, nous allons créer un composant .NET, le marquer comme composant visible COM, l'utiliser à l'exécution dans VB6 et l'attacher à ses événements.

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

La plupart des développeurs ont souvent besoin de l'automatisation d'Internet Explorer, ce qui signifie essentiellement ouvrir un navigateur, remplir certains formulaires et publier des données par programmation.

L'approche la plus courante consiste à utiliser shdocvw.dll (le contrôle du navigateur Web Microsoft) et Mshtml.dll (le composant d'analyse et de rendu HTML), ou Microsoft.Mshtml.dll qui est en fait un wrapper .NET pour Mshtml.dll. Vous pouvez obtenir plus d'informations sur Internet Explorer - À propos du navigateur ici.

Si vous choisissez la méthode et les DLL ci-dessus, voyons certains des problèmes que vous devrez peut-être résoudre:

Vous devez distribuer ces DLL car votre projet dépendrait de ces DLL, et c'est un problème grave si vous ne pouvez pas les déployer correctement. Faites simplement une recherche sur les problèmes de distribution de shdocvw et mshtml.dll, et vous verrez de quoi je parle. Vous devez déployer un Microsoft.mshtml.dll de 8 Mo car cela DLL ne fait pas partie du framework .NET. Dans ce cas, ce que nous devons faire est d'utiliser une technique de liaison tardive. Écriture nos propres wrappers pour les DLL mentionnées ci-dessus. Et bien sûr, nous le ferons car il est plus utile que d'utiliser ces DLL. Par exemple, nous n'aurons pas besoin de vérifier si l'opération de téléchargement de document est terminée car IEHelper le fera pour nous.

1
csexpert