所以我有这样的继承链:
class a : {}
class a<T> : {}
class b: a<int> {}
class c: a {}
我需要检查实例(让我们说var inst = new b()
)是继承自a<>
还是仅来自a
。
但是,标准IsAssignableFrom
,IsSubclassOf
,IsInstanceOfType
,is
都不合适。
这样做的正确方法是什么?
UPD1:继承链可能超过1级
答案 0 :(得分:3)
b类的实例不是来自a<T>
,而是来自a<int>
,两者是不同的类型。
var type = inst.GetType();
var result = false;
while (type != typeof(object))
{
type = type.BaseType;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(a<>))
{
result = true;
break;
}
}
//check result
答案 1 :(得分:1)
b
不继承自a<>
,它继承自a<int>
。但是,您可以通过反射检查基类的泛型类型定义是否为a<>
:
type t = typeof(b).BaseType;
return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(a<>);
答案 2 :(得分:1)
使用您的更新(更多继承级别),您可以拥有:
public static bool IsGenericA(object instance)
{
Type t = instance.GetType();
while(t.BaseType != null && t.BaseType != typeof(object))
t = t.BaseType;
return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(a<>);
}
public static bool IsNonGenericA(object instance)
{
Type t = instance.GetType();
while(t.BaseType != null && t.BaseType != typeof(object))
t = t.BaseType;
return t == typeof(a);
}
See it in action in this fiddle
只要基数为a
或a<something>
答案 3 :(得分:1)
假设你有这个层次结构:
class a { }
class a<T> : a { }
class b : a<int> { }
class c : a { }
您需要探索继承树以获取基类泛型类型并测试其泛型类型定义。但是,如果您正在寻找一些通用的解决方案,则必须考虑接口实现案例。
,例如,如果您的层次结构将被重写为:
interface a { }
interface a<T> : a { }
class b : a<int> { }
class c : a { }
这将“中断”继承树遍历,因为b
的基本类型将是System.Object
而不是a<T>
。也就是说,继承和接口实现是两回事。
我会这样实现它:
internal static class TypeExtensions
{
private static bool IsInheritedFromGenericTypeDefinition(Type type, Type baseType)
{
do
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == baseType)
return true;
type = type.BaseType;
}
while (type != null);
return false;
}
public static bool IsInheritedFrom(this Type type, Type baseType)
{
if (baseType.IsGenericTypeDefinition)
{
if (!type.IsInterface && baseType.IsInterface)
{
do
{
// since baseType is an interface, and source type is not,
// we can't test inheritance tree anymore;
// instead, we have to obtain implemented interfaces and test them
var implementedInterfaces = type.GetInterfaces();
if (implementedInterfaces.Any(intf => IsInheritedFromGenericTypeDefinition(intf, baseType)))
return true;
type = type.BaseType;
}
while (type != null);
return false;
}
else
return IsInheritedFromGenericTypeDefinition(type, baseType);
}
return baseType.IsAssignableFrom(type);
}
}
结果:
a - &gt;一个&LT;&GT; =真
b - &gt;一个&LT;&GT; =真实 b - &gt; a =真实 b - &gt; a =真
c - &gt; a =真实 c - &gt;一个&LT;&GT; =假
答案 4 :(得分:0)
typeOf()怎么样?您可以使用此
获取父类答案 5 :(得分:0)
class a : {}
class a<T> : {}
对不起,但在C#a
和a<T>
完全不同。他们都以字母a
开头的事实是巧合。
因此,为了区分,您可以使用is operator。
if (inst is a)
{
// derived from a
}
else
{
// not derived from a
}