2009-08-02 7 views
11

ich mit der Erklärung, mein Szenario in Code beginnt:C# .NET - Wie bekomme ich typeof() um mit Vererbung zu arbeiten?

public class A { } 

public class B : A { } 

public class C : B { } 

public class D { } 

public class Test 
{ 
    private A a = new A () ; 
    private B b = new B () ; 
    private C c = new C () ; 
    private D d = new D () ; 

    public Test () 
    { 
     // Evaluates to "false" 
     if (a.GetType == typeof(B)) { } //TODO: Add Logic 

     // Evaluates to "true" 
     if (b.GetType == typeof(B)) { } //TODO: Add Logic 

     // I WANT this to evaluate to "true" 
     if (c.GetType == typeof(B)) { } //TODO: Add Logic 

     // Evaluates to "false" 
     if (d.GetType == typeof(B)) { } //TODO: Add Logic 
    } 
} 

Die wichtige Linie von hier zu beachten ist:

if (c.GetType == typeof(B)) { } 

Ich glaube, dass dies in der Tat beurteilen zu " false ", da Typ (B) und Typ (C) in beiden Richtungen nicht gleich sind. (C ist ein B, aber B ist nicht unbedingt ein C.)

Aber was ich brauche, ist eine Art von Bedingung, die dies berücksichtigen wird. Wie kann ich feststellen, ob ein Objekt ein B oder etwas davon ist?

Es ist mir egal, ob es sich um ein von B abgeleitetes Objekt handelt, solange die Basis B-Klasse da ist. Und ich kann nicht voraussehen, welche abgeleitete Klasse in meiner Anwendung angezeigt werden könnte. Ich muss einfach davon ausgehen, dass in Zukunft unbekannte Klassen existieren werden - und deshalb kann ich mich nur darauf konzentrieren, sicherzustellen, dass die Basisklasse das ist, was ich erwarte.

Ich brauche eine Bedingung, die diese Prüfung für mich durchführen wird. Wie kann dies erreicht werden?

+0

Sie sollten diese Art von Logik wo möglich vermeiden. Wenn Sie feststellen müssen, was der abgeleitete Typ eines Objekts ist, verwenden Sie den Polymorphismus nicht gut. –

+0

Siehe meinen Kommentar zu Steven Sudits Antwort. – Giffyguy

Antwort

36

können Sie nur is verwenden:

if (c is B) // Will be true 

if (d is B) // Will be false 
+0

Als Antwort auf die einzige Frage im OP: "Wie kann ich feststellen, ob ein Objekt ein B oder etwas daraus ist?" Das ist die richtige Antwort. Mine ist die Antwort auf den Thread-Titel, aber weniger geeignet für das beschriebene Problem. –

+0

Ah, wahr genug. Du hast Recht, meine Frage ist ein wenig verwirrt. Mein Fehler. – Giffyguy

+0

+1 Dies ist die richtige Lösung für dieses Problem. –

19

Edit: Dies beantwortet die Frage im Thread-Titel. cdm9002 hat die bessere Antwort auf das Problem, wie im vollständigen Beitrag beschrieben.

typeof(B).IsAssignableFrom(c.GetType()) 
+2

Die Antwort von cdm9002 ist besser, da keine Reflexion verwendet wird. –

+0

@pb: Wenn Sie technische erhalten möchten, verwendet die andere Antwort nicht 'typeof' mit Vererbung. Wie Sie aus meiner Bearbeitung sehen können, bin ich nicht derjenige, der behauptet, dass die erste Antwort, von der ich dachte, die passendste ist.:) –

+2

Dies ist nicht nur eine vollkommen richtige Antwort, sondern deckt auch den Fall ab, wenn Sie keine Instanzen einer der Klassen zur Hand haben, aber immer noch feststellen wollen, ob zwischen zwei Typen eine Vererbungsbeziehung besteht. –

4

Das sieht wie ein Job für Polymorphismus, im Gegensatz zu einer großen switch-Anweisung mit Tests für bestimmte Klassen.

+0

In der Tat. Setzen Sie eine virtuelle Methode auf Klasse A, überschreiben Sie sie gegebenenfalls in Unterklassen, und rufen Sie dann diese virtuelle Methode auf. –

+1

Wie unhöflich !! Haha. Meine Klassenlogik sieht nicht wirklich so aus. Ich musste nur herausfinden, wie man diese Bedingung erfüllt. Ich schreibe eine PropertyChangedCallback-Methode in der abstrakten Basisklasse, und ich brauche eine Sicherheitsbedingung, die sicherstellen wird, dass der DependencyObject-Parameter ein Objekt ist, das von meiner Basisklasse abgeleitet ist. Wenn nicht, erhalte ich einen Fehler oder annulliere meine Logik. Polymorphismus ist in diesem Fall nicht hilfreich. – Giffyguy

+1

Ok, dann sollte "is" genügen. –

0

Für VB.NET mit Visual Studio     2008 können Sie es überprüfen möchten:

'MyTextBox control is inherited by Textbox 
If Ctl.GetType.Name = "MyTextBox" then  

End If 
1

Als Alternative zu der (c is B) Prüfung können Sie auch Folgendes tun:

var maybeB = c as B; 
if (maybeB != null) { 
    // make use of maybeB 
} 

Dies ist in einigen Fällen vorzuziehen, da Sie c als B verwenden müssen, wenn Sie is verwenden, müssten Sie trotzdem werfen.

0
typeof(B).IsInstanceOfType(c) 

Ähnlich wie die Antwort oben von sam-harwell, manchmal können Sie den Typ „B“ haben in einer Variablen, so dass Sie Reflexion eher als die verwenden müssen „ist“ Operator.

Ich benutzte Sams Lösung und war angenehm überrascht, als Resharper diesen Vorschlag machte.

Verwandte Themen