Видимо, нет.
Вот варианты:
Type.IsSubclassOf
Как вы уже узнали, это не будет работать, если два типа одинаковы, вот пример программы LINQPad, которая демонстрирует:
void Main()
{
typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}
public class Base { }
public class Derived : Base { }
Вывод:
True
False
Что указывает на то, что Derivedэто подкласс Base, но это Base(очевидно) не подкласс сам по себе.
Type.IsAssignableFrom
Теперь это ответит на ваш конкретный вопрос, но также даст вам ложные срабатывания. Как отметил Эрик Липперт в комментариях, хотя метод действительно вернется Trueдля двух вышеупомянутых вопросов, он также вернется Trueдля них, которые вы, вероятно, не хотите:
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 { }
Здесь вы получите следующий вывод:
True
True
True
Последнее Trueуказывало бы, если бы метод отвечал только на заданный вопрос, что uint[]наследует int[]или что они одного типа, что явно не так.
Так что IsAssignableFromэто не совсем правильно.
is и as
«Проблема» isи asв контексте вашего вопроса заключается в том, что они потребуют от вас работать с объектами и писать один из типов непосредственно в коде, а не работать с Typeобъектами.
Другими словами, это не скомпилируется:
SubClass is BaseClass
^--+---^
|
+-- need object reference here
и не будет этого:
typeof(SubClass) is typeof(BaseClass)
^-------+-------^
|
+-- need type name here, not Type object
и не будет этого:
typeof(SubClass) is BaseClass
^------+-------^
|
+-- this returns a Type object, And "System.Type" does not
inherit from BaseClass
Вывод
Хотя приведенные выше методы могут соответствовать вашим потребностям, единственный правильный ответ на ваш вопрос (на мой взгляд) заключается в том, что вам потребуется дополнительная проверка:
typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);
что, конечно, имеет больше смысла в методе:
public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
return potentialDescendant.IsSubclassOf(potentialBase)
|| potentialDescendant == potentialBase;
}