2009-01-27 8 views
71

Ich versuche, mich um den Kopf zu kümmern, wenn die frühe/späte Bindung in C# auftritt.Frühe und späte Bindung

Nicht-virtuelle Methoden sind immer früh gebunden. Virtuelle Methoden sind immer spät gebunden: Der Compiler fügt zusätzlichen Code ein, um die tatsächliche Methode zu lösen, an die zur Ausführungszeit eine Bindung hergestellt wird, und überprüft die Typsicherheit. Daher verwendet der Subtyppolymorphismus die späte Bindung.

Aufrufmethoden mit Reflektion ist ein Beispiel für späte Bindung. Wir schreiben den Code, um dies zu erreichen, im Gegensatz zum Compiler. (Zum Beispiel COM-Komponenten aufrufen.)

VB.NET unterstützt implizite späte Bindung, wenn Option Strict deaktiviert ist. Ein Objekt ist spät gebunden, wenn es einer Variablen zugewiesen wird, die als Objekt definiert ist. Der VB-Compiler fügt Code ein, um zur Ausführungszeit an die richtige Methode zu binden und ungültige Aufrufe abzufangen. C# unterstützt diese Funktion nicht.

Gehe ich in die richtige Richtung?

Wie wäre es, Delegaten aufzurufen und eine Methode über eine Schnittstellenreferenz aufzurufen? Ist das früh oder spät verbindlich?

Antwort

89

Alles ist früh in C# gebunden, es sei denn, Sie durchlaufen die Reflection-Schnittstelle.

Early bound bedeutet nur, dass die Zielmethode zur Kompilierungszeit gefunden wird und Code erstellt wird, der diesen Aufruf auslöst. Ob es virtuell ist oder nicht (was bedeutet, dass es einen zusätzlichen Schritt gibt, um es zur Anrufzeit zu finden, ist irrelevant). Wenn die Methode nicht existiert, kann der Compiler den Code nicht kompilieren.

Spät gebunden bedeutet, dass die Zielmethode zur Laufzeit gesucht wird. Oft wird der Textname der Methode verwendet, um nachzuschlagen. Wenn die Methode nicht da ist, bang. Das Programm wird zum Laufzeitende abstürzen oder in ein Ausnahmebehandlungsschema einsteigen.

Die meisten Skriptsprachen verwenden späte Bindung, und kompilierte Sprachen verwenden frühe Bindung.

C# (vor Version 4) bindet nicht zu spät; Sie können jedoch die Reflexions-API dazu verwenden. Diese API kompiliert zu Code, der nach Funktionsnamen sucht, indem er zur Laufzeit durch Assemblys gräbt. VB kann spät binden, wenn Option Strict deaktiviert ist.

Bindung wirkt sich normalerweise auf die Leistung aus. Da eine späte Bindung zur Laufzeit Abfragen erfordert, bedeutet dies normalerweise, dass Methodenaufrufe langsamer sind als Aufrufe von frühen gebundenen Methoden.


Für eine normale Funktion kann der Compiler seine numerische Position im Speicher ermitteln. Wenn dann die Funktion aufgerufen wird, kann sie eine Anweisung zum Aufrufen der Funktion an dieser Adresse erzeugen.

Für ein Objekt mit virtuellen Methoden generiert der Compiler eine V-Tabelle. Dies ist im Wesentlichen ein Array, das die Adressen der virtuellen Methoden enthält. Jedes Objekt, das über eine virtuelle Methode verfügt, enthält ein ausgeblendetes Element, das vom Compiler generiert wird und die Adresse der v-Tabelle ist. Wenn eine virtuelle Funktion aufgerufen wird, ermittelt der Compiler die Position der entsprechenden Methode in der v-Tabelle. Es erzeugt dann Code, um in die Objekte v-Tabelle zu schauen und die virtuelle Methode an dieser Position aufzurufen.

So gibt es eine Suche, die für die virtuelle Funktion auftritt. Dies ist stark optimiert, so dass es zur Laufzeit sehr schnell passieren wird.

gebunden Früh

  • Der Compiler arbeiten können, wo die aufgerufene Funktion bei der Kompilierung wird.
  • Der Compiler kann früh garantieren (vor eines der Programme Code ausgeführt wird), dass die Funktion existieren und zur Laufzeit kündbar sein.
  • Der Compiler garantiert, dass die Funktion die richtige Anzahl von Argumenten akzeptiert und dass sie vom richtigen Typ sind. Es überprüft auch, dass der Rückgabewert vom richtigen Typ ist.

späte Bindung

  • Die Lookup wird länger dauern, weil es nicht eine einfache Berechnung Offset-, gibt es in der Regel Textvergleiche vorgenommen werden.
  • Die Zielfunktion ist möglicherweise nicht vorhanden.
  • Die Zielfunktion, die Argumente nicht akzeptieren können, an sie übergeben und einen Rückgabewert vom falschen Typ haben.
  • Bei einigen Implementierungen kann die Zielmethode tatsächlich zur Laufzeit geändert werden. Daher kann die Suche eine andere Funktion ausführen. Ich denke, das passiert in der Sprache Ruby. Sie können eine neue Methode für ein Objekt definieren, während das Programm läuft. Bei der späten Bindung können Funktionsaufrufe eine neue Überschreibung für eine Methode aufrufen, anstatt die vorhandene Basismethode aufzurufen.
+0

Ich denke, Sie wollten sagen "Die VB-Sprache selbst bindet nicht spät ..." –

+0

Eigentlich benutze ich VB nicht, also weiß ich nicht viel darüber. Ich meinte C#, aber es sieht so aus, als würde ich mich nur wiederholen. Ich könnte mir aber vorstellen, dass du Recht hast, also repariere ich es! –

+0

Mit dem dynamischen Schlüsselwort wird die späte Bindung in C# 4 verfügbar sein. – configurator

16

C# 3 verwendet die frühe Bindung.

C# 4 fügt die späte Bindung mit dem dynamic Stichwort. Details finden Sie unter Chris Burrow's blog entry zum Thema.

Wie für virtuelle im Vergleich zu nicht-virtuellen Methoden, dies ist ein anderes Thema. Wenn ich string.ToString() aufrufen, ist der C# -Code an die virtuelle object.ToString()-Methode gebunden. Der Code des Aufrufers ändert sich nicht basierend auf dem Objekttyp. Vielmehr werden virtuelle Methoden über eine Tabelle von Funktionszeigern aufgerufen. Eine Objektinstanz verweist auf die Tabelle des Objekts, die auf die Methode ToString() verweist. Eine Instanz der Zeichenfolge hat ihre virtuelle Methodentabelle, die auf ihre ToString() Methode zeigt. Ja, das ist Polymorphie. aber es ist keine späte Bindung.

+1

Ich stimme dieser Erklärung nicht vollständig zu. Wenn in C# eine Instanzmethode oder ein Feld als virtuelle Methode markiert ist, kann der abgeleitete Typ die Implementierung des Basistyps in der Vererbungskette überschreiben. Mit virtuellen Methoden weiß die CLR, welche Methode zur Laufzeit auf der Grundlage der Laufzeitobjekt-Instanz aufgerufen wird. Wahrscheinlich, der einzige Teil, dem ich zustimme, ist, dass es eine Implementierung von Polymorphismus ist. Dann verursachen Sie Verwirrung, indem Sie sagen, dass es keine späte Bindung ist. Es handelt sich um eine späte Bindung, da CLR nur dann die korrekte Laufzeittypimplementierung aufrufen kann, wenn sie den Laufzeittyp der Objektinstanz kennt. –

4

In den meisten Fällen ist die frühe Bindung, was wir auf einer täglichen Basis zu tun. Wenn zum Beispiel eine Klasse Employee zum Zeitpunkt der Kompilierung verfügbar ist, erstellen wir einfach die Instanz dieser Klasse und rufen Instanzelemente auf. Dies ist früh verbindlich.

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

Auf der anderen Seite, wenn Sie das Wissen der Klasse bei der Kompilierung nicht haben, dann ist der einzige Weg spät bindet an Reflexion verwendet wird. Ich bin auf ein ausgezeichnetes Video gestoßen, das diese Konzepte erläutert - here's the link.

2

In sehr einfachen Worten, frühe Bindung geschieht zur Kompilierzeit und der Compiler hat das Wissen über den Typ und alle seine Mitglieder, und späte Bindung geschieht zur Laufzeit, der Compiler weiß nichts über den Typ und seine Mitglieder . Ich bin auf ein ausgezeichnetes Video auf youtube gestoßen, das diese Konzepte erklärt.

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

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

3

Es ist eine sehr alte Post wollte aber mehr Informationen, um es hinzuzufügen. Late Binding wird verwendet, wenn Sie das Objekt nicht zur Kompilierzeit instanziieren möchten. In C# verwenden Sie Activator, um Bind-Objekt zur Laufzeit aufzurufen.

3

Frühe Bindung

Der Name selbst beschreibt, dass Compiler weiß, welche Art von Objekt es sich handelt, was sind alle Methoden und Eigenschaften enthält. Sobald Sie das Objekt deklariert haben, füllt .NET Intellisense seine Methoden und Eigenschaften mit einem Klick auf den Punkt-Button.

Häufige Beispiele:

ComboBox cboItems;

ListBox lstItems; Wenn wir in den obigen Beispielen das cboItem eingeben und einen Punkt gefolgt von setzen, werden automatisch alle Methoden, Ereignisse und Eigenschaften eines Kombinationsfelds aufgefüllt, da der Compiler bereits weiß, dass es sich um eine Combobox handelt.

später Bindung

Der Name selbst beschreibt, dass Compiler nicht weiß, welche Art von Objekt es sich handelt, was sind alle Methoden und Eigenschaften enthält. Sie müssen es als ein Objekt deklarieren, später müssen Sie den Typ des Objekts abrufen, Methoden, die darin gespeichert sind. Alles wird zur Laufzeit bekannt sein.

Häufige Beispiele:

Objekt objItems;

objItems = CreateObject ("DLL oder Assemblyname"); Hier wird während der Kompilierzeit der Typ von objItems nicht bestimmt. Wir erstellen ein Objekt einer DLL und weisen es den objItems zu, so dass alles zur Laufzeit festgelegt wird.

Early Binding gegen Spät

Bindung

nun in die pictureâ € kommenden |

Anwendung läuft schneller in der frühen Bindung, da keine Boxen oder Unboxing sind hier fertig.

einfacher, den Code in der frühen Bindung zu schreiben, da die Intellisense automatisch

Minimal-Fehler in der frühen Bindung bevölkert werden, da die Syntax während der Kompilierung selbst überprüft wird.

Späte Bindung würde in allen Arten von Versionen unterstützen, da alles zur Laufzeit entschieden wird.

Minimale Auswirkungen von Code in zukünftigen Erweiterungen, wenn Late Binding verwendet wird.

Leistung wird Code in der frühen Bindung sein. Beide haben Vor- und Nachteile, es ist die Entscheidung des Entwicklers, basierend auf dem Szenario die passende Bindung auszuwählen.