我有一个类:
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
怎么做?
答案 0 :(得分:1)
稍微误解了这个问题......这就是我在那种情况下会做的事情 - 但请注意下面的示例只能在1级深度工作。如果您认为或知道其他对象将从B派生,则循环直到BaseType为object并使用当前类型名称。或者,您可以密封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);
}
}
答案 1 :(得分: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;
}
答案 2 :(得分: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;
}