Es gibt ein wichtiges und subtiles Problem, das keiner von ihnen direkt anspricht. Es gibt zwei Möglichkeiten, den Typ in C # zu berücksichtigen: den statischen Typ und den Laufzeittyp .
Der statische Typ ist der Typ einer Variablen in Ihrem Quellcode. Es ist daher ein Konzept zur Kompilierungszeit. Dies ist der Typ, den Sie in einem Tooltip sehen, wenn Sie mit der Maus über eine Variable oder Eigenschaft in Ihrer Entwicklungsumgebung fahren.
Sie können einen statischen Typ erhalten, indem Sie eine generische Hilfsmethode schreiben, damit die Typinferenz dies für Sie erledigt:
Type GetStaticType<T>(T x) { return typeof(T); }
Der Laufzeittyp ist der Typ eines Objekts im Speicher. Es ist daher ein Laufzeitkonzept. Dies ist der von der GetType()Methode zurückgegebene Typ .
Der Laufzeittyp eines Objekts unterscheidet sich häufig vom statischen Typ der Variablen, Eigenschaft oder Methode, die es enthält oder zurückgibt. Sie können beispielsweise folgenden Code verwenden:
object o = "Some string";
Der statische Typ der Variablen ist object, aber während der Laufzeit, die Art der Variable referent ist string. Daher wird in der nächsten Zeile "System.String" auf der Konsole gedruckt:
Console.WriteLine(o.GetType()); // prints System.String
Wenn Sie jedoch mit der Maus über die Variable oin Ihrer Entwicklungsumgebung fahren, wird der Typ System.Object(oder das entsprechende objectSchlüsselwort) angezeigt. Sie sehen dasselbe auch mit unserer Hilfsfunktion von oben:
Console.WriteLine(GetStaticType(o)); // prints System.Object
Für Value-Typen Variablen, wie int, double, System.Guid, wissen Sie , dass der Laufzeittyp immer gleich den statischen Typen sein, da die Value - Typen können nicht als Basisklasse für eine andere Art dienen; Der Werttyp ist garantiert der am meisten abgeleitete Typ in seiner Vererbungskette. Dies gilt auch für versiegelte Referenztypen: Wenn der statische Typ ein versiegelter Referenztyp ist, muss der Laufzeitwert entweder eine Instanz dieses Typs sein oder null.
Wenn umgekehrt der statische Typ der Variablen ein abstrakter Typ ist, ist garantiert, dass der statische Typ und der Laufzeittyp unterschiedlich sind.
Um dies im Code zu veranschaulichen:
// int is a value type
int i = 0;
// Prints True for any value of i
Console.WriteLine(i.GetType() == typeof(int));
// string is a sealed reference type
string s = "Foo";
// Prints True for any value of s
Console.WriteLine(s == null || s.GetType() == typeof(string));
// object is an unsealed reference type
object o = new FileInfo("C:\\f.txt");
// Prints False, but could be true for some values of o
Console.WriteLine(o == null || o.GetType() == typeof(object));
// FileSystemInfo is an abstract type
FileSystemInfo fsi = new DirectoryInfo("C:\\");
// Prints False for all non-null values of fsi
Console.WriteLine(fsi == null || fsi.GetType() == typeof(FileSystemInfo));
int