如何在不实例化的情况下测试两个泛型是否具有基子类关系

本文关键字:是否 泛型 两个 关系 子类 实例化 测试 情况下 | 更新日期: 2023-09-27 17:49:45

我有以下通用类:

class Base<T> where T : ... { ... }
class Derived<T> : Base<T> where T : ... { ... }
class Another<T> where T : ... { ... }
class DerivedFromDerived<T> : Derived<T> where T : ... { ... }

在我的代码中,我想测试给定的泛型是否继承自Base<T>,而不创建泛型的特定实例。我该怎么做?

static bool DerivedFromBase(Type type) { /* ??? */ }
static void Main(string[] args)
{
    Console.WriteLine(DerivedFromBase(typeof(Derived<>)));            // true
    Console.WriteLine(DerivedFromBase(typeof(Another<>)));            // false
    Console.WriteLine(DerivedFromBase(typeof(DerivedFromDerived<>))); // true
    Console.ReadKey(true);
}

编辑:谢谢马克。现在我看到了光明。我最初尝试了以下内容:

typeof(Derived<>).BaseType == typeof(Base<>)

显然,这是正确的但事实并非如此问题是Base的T和Derived的T不是一回事。所以,在中

typeof(Base<>)

BaseT是一个自由类型。但是,在

typeof(Derived<>).BaseType

BaseT绑定到DerivedT,后者又是一个自由类型。(这太棒了,我很想看看System.Reflection的源代码!(现在,

typeof(Derived<>).BaseType.GetGenericTypeDefinition()

对CCD_ 11的CCD_。结论:

typeof(Derived<>).BaseType.GetGenericTypeDefinition() == typeof(Base<>)

现在,如果你们都原谅我的话,我的头在燃烧。

如何在不实例化的情况下测试两个泛型是否具有基子类关系

不确定这是否是您想要的,但我认为"IsAssignableFrom"会起作用。

class Program
{
    class Base<T> { }
    class Derived<T> : Base<T> { }
    class Another<T> { }
    class DerivedFromDerived<T> : Derived<T> { }
    static bool DerivedFromBase<T>(Type type)
    {
        return typeof(Base<T>).IsAssignableFrom(type);
    }
    static void Main(string[] args)
    {
        Console.WriteLine(DerivedFromBase<int>(typeof(Derived<int>)));            // true    
        Console.WriteLine(DerivedFromBase<int>(typeof(Another<int>)));            // false    
        Console.WriteLine(DerivedFromBase<int>(typeof(DerivedFromDerived<int>))); // true   
        Console.ReadKey(true);
    }
}

处理开放式底座类型:

static bool DerivedFromBase(Type type)
    {
        Type openBase = typeof(Base<>);
        var baseType = type;
        while (baseType != typeof(Object) && baseType != null)
        {
            if (baseType.GetGenericTypeDefinition() == openBase) return true;
            baseType = baseType.BaseType;
        }
        return false;
    }

我已经提出了这个版本,尽管它看起来有点古怪。

private static bool IsDerivedFrom(Type derivedType, Type baseType)
{
    if (derivedType.BaseType == null)
        return false;
    if (derivedType.BaseType.GUID == baseType.GUID)
        return true;
    return IsDerivedFrom(derivedType.BaseType, baseType);
}

它依赖于所有类型都有不同的GUID,这应该是真的,但显然下周四会发生冲突。