Was ist eine Besetzung unter der Haube [Duplikat]

8

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;

abweicht

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 !!!

    
Leonardo 27.12.2012, 19:38
quelle

4 Antworten

3

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%

    
Thousand 27.12.2012, 19:45
quelle
2

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.

    
Servy 27.12.2012 19:47
quelle
1

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

definiert

Hier ist der ILDASM für System.String.ToString ():

%Vor%

Es gibt nur sich selbst zurück.

    
Nick Bray 27.12.2012 19:54
quelle
1

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>

    
Dinesh 27.12.2012 20:07
quelle

Tags und Links