2010-02-01 4 views
10

Ich habe festgestellt, dass wenn ich folgende Zeilen Code ausführen.Warum müssen einige Funktionen der Object-Klasse in einer primitiven Instanz aufgerufen werden?

int i = 7; 
i.GetHashCode(); //where GetHashCode() is the derived 
       //function from System.Object 

ist kein Boxen getan, aber wenn ich i.GetType() (eine andere abgeleitete Funktion von System.Object) anstelle von GetHashCode() anrufen, wird ein Boxen erforderlich GetType() zu nennen, warum GetType() auf primitive Typ-Instanz anzurufen seine nicht möglich, direkt , ohne Boxen, während es möglich ist, GetHashCode() ohne Boxen zu nennen?

+0

Ich bin überrascht, dass 'GetType' überhaupt genannt wird. Da C# statisch typisiert ist und eine * Werttypvariable * nur Objekte vom Werttyp enthalten kann, ist der Typ beim Kompilierungstyp bestimmbar (es ist 'typeof (int)'). Warum also einen Laufzeitaufruf ausgeben? –

+0

Das ist richtig, aber die Absicht ist hier zu klären, warum die Dinge nicht so funktionieren, wie sie sollten. – waheed

Antwort

8

Der Schlüssel hier ist, dass GetType() ist nicht virtuell und kann nicht überschrieben werden. Da eine Struktur effektiv sealed ist, können Methoden keine mehr als die Struktur überschrieben werden, so dass die Laufzeit und Compiler Strukturmethoden behandeln können, die als statische Aufrufe überschrieben wurden.

Wenn Sie schreiben eine Struktur (selten) Sie sollten außer Kraft setzen alle Methoden wie ToString(), Equals(), GetHashCode() genau diesem Grund. Wenn du es nicht tust, musst du boxen. GetType()kann jedoch nicht überschrieben werden, muss also boxen.

Dies führt tatsächlich zu einigen ungerade Rand-Fälle mit Nullable<T> und Boxen, da eine leere Nullable<T> Boxen null, so:

int i = obj.GetHashCode(); // fine 
Type t = obj.GetType(); // boom 
2

Ich denke, der Grund ist, dass GetHashCode auf System.Int32 direkt implementiert ist, rufen Sie System.Int32 :: GetHashCode(). Wenn Sie eine bekannte Elementfunktion für einen Werttyp aufrufen, ist keine Box erforderlich.

+0

So können die Funktionen, die nicht direkt auf System.Int32 implementiert sind, wie die von System.ValueType oder System.Object, nicht direkt aufgerufen werden? – waheed

+0

Das ist, was ildasm mir bisher gezeigt hat .... Wenn Sie die Basisklassenfunktion (wie System.Object :: GetType() aufrufen, ist Boxen erforderlich. Wenn Sie eine Funktion aufrufen, die auf dem Wertobjekt implementiert ist, dann ist kein Boxen erforderlich ... – Arve