简体   繁体   English

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

[英]How to determine if an object inherits from an abstract generic class

I have a generic abstract class which I derive from: 我有一个通用的抽象类,我派生自:

abstract class SuperClass<T>
where T : SuperDataClass

abstract class SuperDataClass

The data type is limited to SuperDataClass, so every concrete data type must inherit from SuperDataClass. 数据类型仅限于SuperDataClass,因此每个具体数据类型都必须从SuperDataClass继承。 In the end I have pairs of SuperClass and SuperDataClass inheriters, eg: 最后我有一对SuperClass和SuperDataClass继承者,例如:

class DataClassA : SuperDataClass
class ClassA : SuperClass<DataClassA>

class DataClassB : SuperDataClass
class ClassB : SuperClass<DataClassB>

How can I check if an object, eg ClassA inherits from SuperClass without knowing the possible data type? 如何在不知道可能的数据类型的情况下检查对象,例如ClassA是否从SuperClass继承?

I tried the following, which does not work: 我尝试了以下,但不起作用:

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

So how does the if-statement needs to look like? 那么if语句需要怎么样?

Use the IsSubclassOf function in conjunction with the generic type: IsSubclassOf函数与泛型类型结合使用:

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

Where @object is the type you want to check (i copied the naming from your question, but object is no good name because it's the superclass of all classes). @object是你要检查的类型(我从你的问题中复制了命名,但是对象不是好名字,因为它是所有类的超类)。

If you want to check the generic type param as well, use 如果您还想检查泛型类型参数,请使用

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

EDIT: your last comment - non generic type deriving from generic type: 编辑:您的上一条评论 - 从泛型类型派生的非泛型类型:

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

Recursively 递归

Type type2 = type; // type is your type, like typeof(ClassA)

while (type2 != null)
{
    if (type2.IsGenericType && 
        type2.GetGenericTypeDefinition() == typeof(SuperClass<>))
    {
        // found
    }

    type2 = type2.BaseType;
}

Note that this won't work if you are looking for an interface! 请注意,如果您正在寻找接口,这将不起作用!

Apparently all obvious solutions ( IsSubclassOf , IsAssignableFrom , is , as ) do not work in this case. 显然,所有的解决方案明显( IsSubclassOfIsAssignableFromisas )不要在这种情况下工作。 So I tried to force things a bit and came up with this way of testing if a class is SuperClass<Something> : 所以我试着强迫一下,如果一个类是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));
}

Of course, this tests if a class is SuperClass<Something> , not if it inherits from SuperClass<Something> , so the next obvious step would be to write a function that tests all inheritance hierarchy for a suitable class: 当然,这测试一个类是否是 SuperClass<Something> ,而不是它继承自 SuperClass<Something> ,因此下一个明显的步骤是编写一个函数来测试合适的类的所有继承层次结构:

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

        type = type.BaseType;
    }

    return false;
}

With these functions in place, the test you're looking for is: 有了这些功能,您正在寻找的测试是:

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

Here you should have some clue as to what the expected type is. 在这里你应该知道预期的类型是什么。 So in this case I would use the Type.IsSubclassOf Method . 所以在这种情况下我会使用Type.IsSubclassOf方法

An example of it's use is 它的一个例子是

Class1 myClass = new Class1();
DerivedC1 myDClass = new DerivedC1();
Type myClassType = myClass.GetType();
Type myDClassType = myDClass.GetType();

// Returns true.
bool isSubClass = myDClassType.IsSubclassOf(myClassType));

I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM