2013-08-07 8 views
5

ich eine generische abstrakte Klasse, die ich aus ableiten:Wie um zu bestimmen, ob ein Objekt von einer abstrakten generischen Klasse erbt

abstract class SuperClass<T> 
where T : SuperDataClass 

abstract class SuperDataClass 

Der Datentyp SuperDataClass beschränkt ist, so dass jeder konkreter Datentyp von SuperDataClass erben muß . Am Ende habe ich Paare von Oberklasse und SuperDataClass inheriters haben, z.B .:

class DataClassA : SuperDataClass 
class ClassA : SuperClass<DataClassA> 

class DataClassB : SuperDataClass 
class ClassB : SuperClass<DataClassB> 

Wie kann ich überprüfen, ob ein Objekt, zum Beispiel ClassA erbt von SuperClass, ohne den möglichen Datentyp zu kennen?

habe ich versucht, die folgenden, die nicht funktioniert:

if (testObject.GetType().IsAssignableFrom(typeof(SuperClass<SuperDataClass>))) { 
    Console.WriteLine("The test object inherits from SuperClass"); 
} 

Wie funktioniert die if-Anweisung aussehen muss?

+0

Ich bin sehr neugierig, warum Sie dies während der Laufzeit wissen wollen. Können Sie das näher ausführen, um meine Neugier zu befriedigen? –

+0

Versuchen Sie mit * ist * Operator http://msdn.microsoft.com/en-us/library/scekt9xw.aspx – Kimi

+0

Ich habe eine Methoden, die mehrere Arten von Objekten verarbeitet. Sie alle haben eine abstrakte Klasse gemeinsam, die in meinem Beispiel SuperClass stammt. Ich möchte also alle Objekte, die von SuperClass stammen, während der Laufzeit auf die gleiche Weise behandeln. Ich möchte, wenn möglich, nicht für jeden Betontyp eine separate Handhabung haben. – sqeez3r

Antwort

1

Recursively

Type type2 = type; // type is your type, like typeof(ClassA) 

while (type2 != null) 
{ 
    if (type2.IsGenericType && 
     type2.GetGenericTypeDefinition() == typeof(SuperClass<>)) 
    { 
     // found 
    } 

    type2 = type2.BaseType; 
} 

Beachten Sie, dass diese Option, wenn Sie für eine Schnittstelle suchen wird nicht funktionieren!

+0

Aber die innere Typprüfung fehlt, muss von SuperDataClass erben, wie ich das verstanden habe. – Matten

+0

@Matten Seine Frage: 'ClassA erbt von SuperClass, ohne den möglichen Datentyp zu kennen?' Wo 'ClassA' ist' ClassA: SuperClass ' – xanatos

+0

Ok das macht es einfacher. Du hast natürlich Recht. – Matten

1

Verwenden Sie die IsSubclassOf Funktion in Verbindung mit dem allgemeinen Typ:

if (@object.GetType().IsGenericType && 
    @object.GetType().GetGenericTypeDefinition().IsSubclassOf(typeof(SuperClass<>))) { 
    Console.WriteLine("The object inherits from SuperClass"); 
} 

Wo @object der Typ Sie überprüfen möchten, ist (i die Namensgebung aus Ihrer Frage kopiert, aber Objekt ist nicht gut Namen, weil es die übergeordnete Klasse ist aller Klassen).

Wenn Sie den generischen Typ param auch überprüfen möchten, verwenden

if (@object.GetType().IsGenericType && 
    @object.GetType().GenericTypeArguments[0].IsSubclassOf(typeof(SuperDataClass)) && 
    @object.GetType().IsSubclassOf(typeof(Superclass<>))) 

EDIT: Ihre letzte Bemerkung - nicht generische Typgewinnungs von generischen Typ:

if (@object.GetType().IsSubclassOf(typeof(Superclass<>))) 
+1

Leider funktioniert das nicht für generische Klassen. Wenn das Testobjekt (Danke für den Hinweis, änderte ich den Namen) ist vom Typ ClassA es funktioniert nur mit dieser Anweisung: if (@ object.GetType(). IsSubclassOf (typeof (SuperClass ))) { Konsole .WriteLine ("Das Testobjekt erbt von SuperClass"); } Das Problem ist, dass ich den Datentyp auch nicht im Voraus kenne. – sqeez3r

+0

Ich bin mir ziemlich sicher, dass @JonSkeet dieses Verhalten auf der Basis von Zwang/Widerspruch erklären könnte, aber ich vermische sie immer :) – Matten

+0

Ist es möglich, eine Person, die noch nicht an diesem Thema beteiligt ist, mit '@ [Name von Benutzer] '? Entschuldigung für die Off-Topic-Frage. –

0

Hier sollten Sie einige haben Hinweis darauf, was der erwartete Typ ist. In diesem Fall würde ich die Type.IsSubclassOf Method verwenden.

Ein Beispiel für seine Verwendung ist

Class1 myClass = new Class1(); 
DerivedC1 myDClass = new DerivedC1(); 
Type myClassType = myClass.GetType(); 
Type myDClassType = myDClass.GetType(); 

// Returns true. 
bool isSubClass = myDClassType.IsSubclassOf(myClassType)); 

Ich hoffe, das hilft.

+0

Warum die down vote? – MoonKnight

+0

Vielleicht, weil Sie im Prinzip das gleiche wie Matten beantwortet haben und Sie an zweiter Stelle standen. Ich weiß es nicht. Sie antworten, scheint auch gültig zu sein. –

+0

Es ist völliger Müll - ich wusste nichts über die obige Antwort (die ich gewählt habe), bis ich gepostet ... – MoonKnight

1

Offensichtlich funktionieren alle offensichtlichen Lösungen (IsSubclassOf, IsAssignableFrom, is, as) in diesem Fall nicht.Also habe ich versucht, die Dinge ein wenig zu zwingen, und kam mit dieser Art und Weise der Prüfung, wenn eine Klasse SuperClass<Something>:

private bool IsSuperClassOfSomeKindOfSuperDataClass(Type type) 
{ 
    if (!type.IsGenericType) 
     return false; 

    var gtd = type.GetGenericTypeDefinition(); 

    if (gtd != typeof(SuperClass<>)) 
     return false; 

    var genericParameter = type.GetGenericArguments().First(); 

    return genericParameter.IsSubclassOf(typeof(SuperDataClass)); 
} 

Natürlich sind diese Tests, wenn eine Klasse istSuperClass<Something>, nicht, wenn es erben vonSuperClass<Something> , so dass der nächste offensichtliche Schritt eine Funktion zu schreiben wäre, die alle Vererbungshierarchie für eine geeignete Klasse testet:

private bool InheritsFromSuperClassOfSomeKindOfSuperDataClass(Type type) 
{ 
    while (type != typeof(Object)) 
    { 
     if (IsSuperClassOfSomeKindOfSuperDataClass(type)) 
      return true; 

     type = type.BaseType; 
    } 

    return false; 
} 

Mit diesen Funktionen im Ort, der Test für Sie suchen ist:

if (InheritsFromSuperClassOfSomeKindOfSuperDataClass(@object.GetType())) 
    // do stuff... 
+0

Das funktioniert auch. Vielen Dank! Während Ihre Lösung detaillierter und einfacher zu verstehen ist, ist die Lösung von xanatos kompakter. – sqeez3r

Verwandte Themen