Ich möchte wissen, was unter der Haube der .Net CLR passiert, wenn ich etwas wie
mache %Vor% und wie die zweite Zeile von string myStr = myObj.ToString()
oder string myStr = myObj as string;
Ich schaute mich um, ich fand Generika-Antworten wie "der Compiler fügt Code dort ein", aber ich bin nicht zufrieden ... Ich suche nach tiefem Understanding der Cast-Mechanik ... Oh, der Compiler fügt Code ein? Zeig es mir! Der Compiler optimiert den Code? Wie? Wann?
Bitte kommen Sie so nah wie möglich an das Metall !!!
Sie können IL Dissasebler verwenden, um zu sehen, was ist von Ihrem Code auf einer niedrigeren Ebene produziert werden. Wenn Sie Visual Studio auf Ihrem Computer installiert haben, sollten Sie in der Lage sein, es zu finden, indem Sie einfach "ildasm" in das Windows-Suchfeld eingeben.
Hier sehen Sie, wie die IL des folgenden Codes aussieht:
%Vor%
Ein Cast ist primär ein Kompilierzeitkonstrukt. Es ist Ihre Art, dem Compiler zu sagen: "Ich weiß besser als Sie, diese Instanz, von der Sie denken, dass sie so ist, und solch ein Typ ist * tatsächlich * von diesem anderen Typ. Tun Sie nur, dass es wirklich dieser andere Typ ist und lassen Sie mich alle benutzen die Methoden / Eigenschaften / Felder / usw. dieses anderen Typs.
Zur Laufzeit ändert sich kaum etwas. Das einzige, was hinzugefügt wird, ist ein Häkchen, um sicherzustellen, dass die Instanz wirklich von dem Typ ist, auf den Sie zu werfen versucht haben, und wenn dies nicht der Fall ist, wird eine Ausnahme ausgelöst. Es ist mehr oder weniger:
%Vor% Wie bei ToString
ist es nur eine Methode, die string
zurückgibt. Die Definition in der Klasse string
ist höchstwahrscheinlich nur return this;
. In jedem Fall wird nichts technisch umgesetzt, Sie rufen nur eine Methode auf, die jedes Objekt hat, die eine Zeichenkette zurückgibt, und wenn dieses Objekt ein string
unter der Haube ist, bekommen Sie gerade das gleiche Objekt zurück. Der Schlüssel ist, dass der Compiler weiß, dass das Ergebnis des Methodenaufrufs immer eine Zeichenkette ist, also muss nichts besonderes getan werden.
Sie können ILDASM verwenden, das mit Visual Studio geliefert wird. Es ist ein IL Disassembler.
Hier ist der Code:
%Vor%Folgendes habe ich:
%Vor%Mit ToString ():
%Vor%Die IL ist:
%Vor%Wenn Sie die Zeichenkette "abc" in Position 0 speichern, dann wird die Position 0 geladen. Der Wert wird mit "Cast Class [mscorlib] System.String" umgewandelt, dann wird dieser Wert in Position 1 gespeichert
Wenn Sie .ToString () aufrufen, ruft sie virtuell System.Object.ToString () für die Zeichenfolge auf. ToString () ist in System.String
definiertHier ist der ILDASM für System.String.ToString ():
%Vor%Es gibt nur sich selbst zurück.
Mit CLR können Sie ein Objekt in seinen Typ oder einen Basistyp umwandeln. Ein Cast-to-Base-Typ wird bereits als sicher betrachtet und ist implizit.
für zB.
Objekt s = new String ();
Aber die CLR möchte, dass Sie explizite Umwandlung angeben, wenn Sie auf einen abgeleiteten Typ umwandeln
%Vor%Nun, was passiert, wird es nicht in String konvertiert, sondern geprüft, ob es vom Typ String ist oder nicht. Wenn es sich um einen String vom Typ String handelt, ist der Cast erfolgreich, sonst wird eine InvalidCastExcetion ausgelöst.
Zwei weitere Fälle sind die Verwendung von ist und als -Operatoren
ist Operator: Dies gibt true zurück, wenn die Umwandlung erfolgreich ist, andernfalls false.
z.B.
%Vor%Bevor Sie eine Methode aufrufen, schreiben Sie normalerweise einen Code wie diesen
%Vor%Dies ist ein wenig teuer, weil CLR zweimal umgewandelt wird.
Um dies zu vermeiden, haben wir den Operator als .
als Operator: Gibt den Verweis auf den Typ des überprüften Objekts zurück. else gibt null zurück.
z.B. :
%Vor%Sie können also sehen, dass es bei Verwendung als Operator einen leichten Leistungsschub gibt.
Das ist alles, was die CLR zu bieten hat, wenn es um Gusstypen geht.
Wenn es um Ihren Code geht:
Objekt str="abc";
str.ToString () ruft die ToString-Methode der System.object-Klasse auf, die eine virtuelle Methode ist. Beim Aufruf einer virtuellen Methode prüft CLR den Typ des Objekts, auf das der Aufrufer zeigt.
Hier zeigt str tatsächlich auf ein String-Objekt. Der Compiler generiert also Code, um die ToString-Methode der String-Klasse aufzurufen, die das "abc" als Ausgabe ausgibt. Dieses Konzept ist ein Polymorphismus, bei dem beim Aufrufen einer virtuellen Methode eines beliebigen Typs der tatsächliche Objekttyp zuerst von der CLR abgerufen wird und dann in Ihrem Fall eine geeignete Methode für den richtigen Typ des Objekts als String-Typ aufgerufen wird. stark>