Apparentemente no.
Ecco le opzioni:
Type.IsSubclassOf
Come hai già scoperto, questo non funzionerà se i due tipi sono uguali, ecco un esempio di programma LINQPad che dimostra:
void Main()
{
typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}
public class Base { }
public class Derived : Base { }
Produzione:
True
False
Il che indica che Derivedè una sottoclasse di Base, ma che non Baseè (ovviamente) una sottoclasse di se stessa.
Type.IsAssignableFrom
Ora, questo risponderà alla tua domanda particolare, ma ti darà anche falsi positivi. Come ha sottolineato Eric Lippert nei commenti, mentre il metodo tornerà effettivamente Trueper le due domande precedenti, tornerà anche Trueper queste, che probabilmente non vuoi:
void Main()
{
typeof(Base).IsAssignableFrom(typeof(Derived)).Dump();
typeof(Base).IsAssignableFrom(typeof(Base)).Dump();
typeof(int[]).IsAssignableFrom(typeof(uint[])).Dump();
}
public class Base { }
public class Derived : Base { }
Qui ottieni il seguente output:
True
True
True
L'ultimo Trueindicherebbe, se il metodo rispondesse solo alla domanda posta, che uint[]eredita int[]o che sono dello stesso tipo, il che chiaramente non è il caso.
Quindi IsAssignableFromnon è nemmeno del tutto corretto.
is e as
Il "problema" con ise asnel contesto della tua domanda è che ti richiederanno di operare sugli oggetti e scrivere uno dei tipi direttamente nel codice e non lavorare con gli Typeoggetti.
In altre parole, questo non verrà compilato:
SubClass is BaseClass
^--+---^
|
+-- need object reference here
né questo:
typeof(SubClass) is typeof(BaseClass)
^-------+-------^
|
+-- need type name here, not Type object
né questo:
typeof(SubClass) is BaseClass
^------+-------^
|
+-- this returns a Type object, And "System.Type" does not
inherit from BaseClass
Conclusione
Mentre i metodi di cui sopra potrebbero soddisfare le tue esigenze, l'unica risposta corretta alla tua domanda (come la vedo io) è che avrai bisogno di un controllo extra:
typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);
che ovviamente ha più senso in un metodo:
public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
return potentialDescendant.IsSubclassOf(potentialBase)
|| potentialDescendant == potentialBase;
}