我有一个泛型类在我的项目与派生类。
public class GenericClass<T> : GenericInterface<T>
{
}
public class Test : GenericClass<SomeType>
{
}
是否有任何方法可以查明Type对象是否派生自GenericClass?
t.IsSubclassOf(typeof(GenericClass<>))
不管用。
我有一个泛型类在我的项目与派生类。
public class GenericClass<T> : GenericInterface<T>
{
}
public class Test : GenericClass<SomeType>
{
}
是否有任何方法可以查明Type对象是否派生自GenericClass?
t.IsSubclassOf(typeof(GenericClass<>))
不管用。
当前回答
试试这段代码
static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
while (toCheck != null && toCheck != typeof(object)) {
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
if (generic == cur) {
return true;
}
toCheck = toCheck.BaseType;
}
return false;
}
其他回答
添加到@jaredpar的答案中,下面是我用来检查接口的方法:
public static bool IsImplementerOfRawGeneric(this Type type, Type toCheck)
{
if (toCheck.GetTypeInfo().IsClass)
{
return false;
}
return type.GetInterfaces().Any(interfaceType =>
{
var current = interfaceType.GetTypeInfo().IsGenericType ?
interfaceType.GetGenericTypeDefinition() : interfaceType;
return current == toCheck;
});
}
public static bool IsSubTypeOfRawGeneric(this Type type, Type toCheck)
{
return type.IsInterface ?
IsImplementerOfRawGeneric(type, toCheck)
: IsSubclassOfRawGeneric(type, toCheck);
}
Ex:
Console.WriteLine(typeof(IList<>).IsSubTypeOfRawGeneric(typeof(IList<int>))); // true
试试这段代码
static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
while (toCheck != null && toCheck != typeof(object)) {
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
if (generic == cur) {
return true;
}
toCheck = toCheck.BaseType;
}
return false;
}
JaredPar的代码可以工作,但只适用于一个继承级别。要获得无限级别的继承,请使用以下代码
public bool IsTypeDerivedFromGenericType(Type typeToCheck, Type genericType)
{
if (typeToCheck == typeof(object))
{
return false;
}
else if (typeToCheck == null)
{
return false;
}
else if (typeToCheck.IsGenericType && typeToCheck.GetGenericTypeDefinition() == genericType)
{
return true;
}
else
{
return IsTypeDerivedFromGenericType(typeToCheck.BaseType, genericType);
}
}
简单的解决方案:只需创建并添加第二个非泛型接口到泛型类:
public interface IGenericClass
{
}
public class GenericClass<T> : GenericInterface<T>, IGenericClass
{
}
然后用is as IsAssignableFrom等任何你喜欢的方式检查。
if (thing is IGenericClass)
{
// Do work
{
显然,只有当您能够编辑泛型类(OP似乎具有这种能力)时才有可能,但它比使用神秘的扩展方法更优雅、更可读。
这个游戏已经晚了…我对JarodPar的答案也有另一种排列。
下面是Type. issubclassof (Type),由reflector提供:
public virtual bool IsSubclassOf(Type c)
{
Type baseType = this;
if (!(baseType == c))
{
while (baseType != null)
{
if (baseType == c)
{
return true;
}
baseType = baseType.BaseType;
}
return false;
}
return false;
}
由此,我们看到它并没有做任何过于疯狂的事情,并且类似于JaredPar的迭代方法。到目前为止,一切顺利。这是我的版本(免责声明:没有彻底测试,所以如果你发现问题,请告诉我)
public static bool IsExtension(this Type thisType, Type potentialSuperType)
{
//
// protect ya neck
//
if (thisType == null || potentialSuperType == null || thisType == potentialSuperType) return false;
//
// don't need to traverse inheritance for interface extension, so check/do these first
//
if (potentialSuperType.IsInterface)
{
foreach (var interfaceType in thisType.GetInterfaces())
{
var tempType = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType;
if (tempType == potentialSuperType)
{
return true;
}
}
}
//
// do the concrete type checks, iterating up the inheritance chain, as in orignal
//
while (thisType != null && thisType != typeof(object))
{
var cur = thisType.IsGenericType ? thisType.GetGenericTypeDefinition() : thisType;
if (potentialSuperType == cur)
{
return true;
}
thisType = thisType.BaseType;
}
return false;
}
基本上这只是System的一个扩展方法。类型-我这样做是为了故意将“thisType”类型限制为具体类型,因为我的直接用法是对类型对象的LINQ查询“where”谓词。我相信所有聪明的人都可以把它归结为一个有效的,通用的静态方法,如果你需要:)代码做了一些事情,答案的代码没有
open's it up to to general "extension" - i'm considering inheritance (think classes) as well as implementation (interfaces); method and parameter names are changed to better reflect this input null-validation (meah) input of same type (a class cannot extend itself) short-circuit execution if Type in question is an interface; because GetInterfaces() returns all implemented interfaces (even ones implemented in super-classes), you can simply loop through that collection not having to climb the inheritance tree
其余部分基本上与JaredPar的代码相同