1

我有一个像这样的课程:

class A<T>
{

}

我有另一个派生自上述类的类,例如:

class B : A<X>
{

}

X之上是另一个类。

现在我可以有很多像 B 这样的类,在这些类中,泛型参数可以是其他类。

如何确定 B 类的任何实例是否派生自 A 类?

我试过:

if objB.GetType() is typeof(A<object>) //didn't work, gave false

if objB.GetType() == typeof(A<object>) //didn't work, gave false

if typeof(A<object>).IsAssignableFrom(obj.GetType()) //didn't work, gave false

怎么做 ?

4

3 回答 3

1

有点误解了这个问题......这就是我在这种情况下会做的事情 - 但请注意,下面的示例只能工作 1 级深度。如果您认为或知道其他对象将从 B 派生,则循环直到 BaseType 为对象并使用当前类型名称。或者,您可以密封 B 使其无法派生。

    public class A<T>
    {

    }

    public class X
    {

    }

    public class B : A<X>
    {


    }


    void Test()
    {
        B obj = new B();

        if(b.GetType().BaseType.Name == "A`1")
        {
            Consosle.WriteLine(true);
        }
    }
于 2013-03-06T13:47:53.717 回答
1

这是有问题的;IsAssignableFrom除非您已经知道,否则任何测试都不会在那里工作X。您必须执行以下操作:

static bool IsA(Type type) {
    do {
        type = type.BaseType;
        if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(A<>))
           return true;
    } while(type != null && type != typeof(object));
    return false;
}

或者也得到T

static bool IsA(Type type, out Type t)
{
    do
    {
        type = type.BaseType;
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(A<>))
        {
            t = type.GetGenericArguments()[0];
            return true;
        }
    } while (type != null && type != typeof(object));
    t = null;
    return false;
}
于 2013-03-06T13:48:36.337 回答
0

哦,这对你来说是一些纯粹的邪恶……利用dynamic劫持反射;这里的关键是它dynamic内置了一些基于类型的缓存,所以它不会每次都做繁重的工作(每种类型只有一次):

static void Main()
{
    Console.WriteLine(IsA("abc"));   // False
    Console.WriteLine(IsA(new B())); // True
    Console.WriteLine(IsA(123));     // False
    Console.WriteLine(IsA(new D())); // True - where D : B
}
public static bool IsA(object o)
{
    return (bool)EvilOnlyUseDynamicToCallThis((dynamic)o);
}

private static bool EvilOnlyUseDynamicToCallThis(object o)
{
    return false;
}
private static bool EvilOnlyUseDynamicToCallThis<T>(A<T> a)
{
    return true;
}
于 2013-03-06T14:05:18.423 回答