Aparentemente não.
Aqui estão as opções:
Type.IsSubclassOf
Como você já descobriu, isso não funcionará se os dois tipos forem iguais. Aqui está um exemplo de programa LINQPad que demonstra:
void Main()
{
typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}
public class Base { }
public class Derived : Base { }
Resultado:
True
False
O que indica que Derived
é uma subclasse de Base
, mas que Base
(obviamente) não é uma subclasse de si mesma.
Type.IsAssignableFrom
Agora, isso responderá sua pergunta em particular, mas também fornecerá falsos positivos. Como Eric Lippert apontou nos comentários, embora o método realmente retorne True
para as duas perguntas acima, ele também retornará True
para estas, que você provavelmente não deseja:
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 { }
Aqui você obtém a seguinte saída:
True
True
True
O último True
indica que, se o método respondeu apenas à pergunta, é uint[]
herdado int[]
ou é do mesmo tipo, o que claramente não é o caso.
Portanto, IsAssignableFrom
também não está totalmente correto.
is
e as
O "problema" com is
e as
no contexto de sua pergunta é que eles exigirão que você opere nos objetos e grave um dos tipos diretamente no código, e não trabalhe com Type
objetos.
Em outras palavras, isso não será compilado:
SubClass is BaseClass
^--+---^
|
+-- need object reference here
nem isso:
typeof(SubClass) is typeof(BaseClass)
^-------+-------^
|
+-- need type name here, not Type object
nem isso:
typeof(SubClass) is BaseClass
^------+-------^
|
+-- this returns a Type object, And "System.Type" does not
inherit from BaseClass
Conclusão
Embora os métodos acima possam atender às suas necessidades, a única resposta correta para sua pergunta (como eu a vejo) é que você precisará de uma verificação extra:
typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);
o que obviamente faz mais sentido em um método:
public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
return potentialDescendant.IsSubclassOf(potentialBase)
|| potentialDescendant == potentialBase;
}