如何确定对象是否继承自抽象泛型类

本文关键字:抽象 泛型类 继承 是否 何确定 对象 | 更新日期: 2023-09-27 18:26:39

我有一个通用抽象类,它是从派生的

abstract class SuperClass<T>
where T : SuperDataClass
abstract class SuperDataClass

数据类型仅限于SuperDataClass,因此每个具体数据类型都必须继承自SuperDataClass。最后,我有一对SuperClass和SuperDataClass继承器,例如:

class DataClassA : SuperDataClass
class ClassA : SuperClass<DataClassA>
class DataClassB : SuperDataClass
class ClassB : SuperClass<DataClassB>

在不知道可能的数据类型的情况下,如何检查对象(例如ClassA)是否从SuperClass继承?

我尝试了以下操作,但不起作用:

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

那么if语句应该是什么样子呢?

如何确定对象是否继承自抽象泛型类

递归

Type type2 = type; // type is your type, like typeof(ClassA)
while (type2 != null)
{
    if (type2.IsGenericType && 
        type2.GetGenericTypeDefinition() == typeof(SuperClass<>))
    {
        // found
    }
    type2 = type2.BaseType;
}

请注意,如果您正在寻找接口,这将不起作用!

显然,所有显而易见的解决方案(IsSubclassOfIsAssignableFromisas)在这种情况下都不起作用。所以我试着强迫一些事情,并想出了这种方法来测试一个类是否是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));
}

当然,这会测试一个类是否是SuperClass<Something>,而不是它是否从SuperClass<Something>继承,所以下一个明显的步骤是编写一个函数来测试合适类的所有继承层次结构:

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

有了这些功能,您想要的测试是:

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

将IsSubclassOf函数与泛型类型结合使用

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

其中@object是您要检查的类型(我从您的问题中复制了命名,但对象不是好名字,因为它是所有类中的超类)。

如果您也想检查泛型类型参数,请使用

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

编辑:您的最后一条评论-源自泛型类型的非泛型类型:

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

这里应该有一些关于预期类型的线索。所以在这种情况下,我会使用type.IsSubclassOf方法。

就是一个例子

Class1 myClass = new Class1();
DerivedC1 myDClass = new DerivedC1();
Type myClassType = myClass.GetType();
Type myDClassType = myDClass.GetType();
// Returns true.
bool isSubClass = myDClassType.IsSubclassOf(myClassType));

我希望这能有所帮助。