2010-07-15 10 views
15

Codebeispiel aus MSDN genommenWarum ist Object.GetType() nicht virtuell?

public class Test { 
public static void Main() { 
    MyBaseClass myBase = new MyBaseClass(); 
    MyDerivedClass myDerived = new MyDerivedClass(); 
    object o = myDerived; 
    MyBaseClass b = myDerived; 

    Console.WriteLine("mybase: Type is {0}", myBase.GetType()); 
    Console.WriteLine("myDerived: Type is {0}", myDerived.GetType()); 
    Console.WriteLine("object o = myDerived: Type is {0}", o.GetType()); 
    Console.WriteLine("MyBaseClass b = myDerived: Type is {0}", b.GetType()); }} 

/* 
This code produces the following output. 
mybase: Type is MyBaseClass 
myDerived: Type is MyDerivedClass 
object o = myDerived: Type is MyDerivedClass 
MyBaseClass b = myDerived: Type is MyDerivedClass 
*/ 

wäre es also logisch GetType() virtuell zumindest funktioniert es als virtuelle zu machen? Kann das jemand erklären? Und andere Frage Gibt es noch andere Methoden im .NET Framework, die GetType ähnlich verhalten?

Antwort

16

weil .Net-Framework möchte nicht, dass Sie die GetType() -Methode und spoof über den Typ überschreiben.

Angenommen, Sie können die Methode außer Kraft setzen, was sie sonst noch tun soll, außer dass sie den Typ der Instanz zurückgibt. und wenn Sie die Methode für jede Ihrer Klassen überschreiben, um den Typ der Instanz zurückzugeben, verletzen Sie dann nicht DRY.

+3

und recht so! –

+0

ja. Du hast recht. aber Sie können diese öffentliche Methode in der abgeleiteten Klasse überladen)) – Arseny

+2

@Arseny: Dann ist es nicht dasselbe wie GetType() wie für den Objekttyp definiert. –

2

GetType gibt den tatsächlichen Typ des Objekts zurück. Dies erlaubt uns zu wissen, welches Objekt wir wirklich an unsere Funktion übergeben haben. Viele Methoden des Frameworks benötigen dies, um ihre eigene Funktionalität zu bestimmen - in den meisten Fällen um die Attribute dieser Klasse zu erhalten. Wenn das Framework die Möglichkeit verlieren würde, den realen Typ eines Objekts zu bestimmen, würde das Objekt ebenfalls diesen Typ verlieren.

Wenn Sie die Art innerhalb Ihrer Methode Umfang verwendet wissen möchten - den Typ, den Sie durch den Compiler aufgenommen erklärt oder wurde - man kann eine ziemlich einfache Erweiterung Methode hinzufügen:

public static Type GetCurrentType<T>(this T obj) 
{ 
    return typeof(T); 
} 

public static void Main() 
{ 
    MyBaseClass myBase = new MyBaseClass(); 
    MyDerivedClass myDerived = new MyDerivedClass(); 
    object o = myDerived; 
    MyBaseClass b = myDerived; 

    Console.WriteLine("mybase: Type is {0}", myBase.GetCurrentType()); 
    Console.WriteLine("myDerived: Type is {0}", myDerived.GetCurrentType()); 
    Console.WriteLine("object o = myDerived: Type is {0}", o.GetCurrentType()); 
    Console.WriteLine("MyBaseClass b = myDerived: Type is {0}", b.GetCurrentType()); 
} 

/* 
This code produces the following output. 
mybase: Type is ValidatorTest.MyBaseClass 
myDerived: Type is ValidatorTest.MyDerivedClass 
object o = myDerived: Type is System.Object 
MyBaseClass b = myDerived: Type is ValidatorTest.MyBaseClass 
*/ 
2

Wenn GetType() virtuelle war, ein Die Klasse mit dem Namen HumanBeing kann sie überschreiben und ein Type-Objekt zurückgeben, das Robot darstellt. Dies wird Spoofing genannt und verhindert, dass dies eine der Hauptfunktionen von CLR namens Type Safety ist.

2

Während es wahr ist, dass Sie die Methode object.GetType() nicht überschreiben können, können Sie "neu" verwenden, um es vollständig zu überladen, wodurch ein anderer bekannter Typ gespooft wird. Das ist interessant, aber ich habe noch nicht herausgefunden, wie man eine Instanz des "Type" -Objekts von Grund auf neu erstellt, also gibt das folgende Beispiel vor, ein anderer Typ zu sein.

public class NotAString 
{ 
    private string m_RealString = string.Empty; 
    public new Type GetType() 
    { 
     return m_RealString.GetType(); 
    } 
} 

Nachdem eine Instanz dieser Erstellen (new NotAString()). GetType(), wird in der Tat die Art für einen String zurück.

+1

Fast alles, was "GetType" betrachtet, hat eine Instanz von "object" oder zumindest einen Basistyp, den sie steuern oder über den sie nachdenken können. Wenn Sie bereits eine Instanz des am meisten abgeleiteten Typs haben, müssen Sie 'GetType' nicht aufrufen. Der Punkt ist so lange, wie jemand 'GetType' auf einem' Objekt' verwendet, dass sie sicher sein können, dass es die Systemimplementierung ist, nicht irgendeine andere benutzerdefinierte Definition. – Servy

0

Ändern von Dr Snooze des answer, um Typ "Objekt von Grund auf neu "auf" eine Instanz des erstellen":

public class NotAString 
{ 
    public new Type GetType() 
    { 
     return typeof(string); 
    } 
} 
Verwandte Themen