Ответ 1
По-видимому, нет.
Здесь варианты:
- Используйте Type.IsSubclassOf
- Используйте Type.IsAssignableFrom
-
is
иas
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;
}