我有以下通用类:
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<>)
Base
的T
是一个自由类型。但是,在
typeof(Derived<>).BaseType
Base
的T
绑定到Derived
的T
,后者又是一个自由类型。(这太棒了,我很想看看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,这应该是真的,但显然下周四会发生冲突。