Type.IsSubclssOf and Type.IsAssignableFrom
这个类有两个非常有用的方法: 和。允许调用者在运行时确定任意两个类型是否有继承关系。
IsSubClassOf
微软MSDN文档上对IsSubClassOf的描述如下:
Determines whether the class represented by the current Type derives from the class represented by the specified Type. 确定当前类是否由指定的类型派生而来
下面来看一些测试代码:
public class ClassA { } public class ClassB : ClassA { } public class ClassC : ClassB { } ... Console.WriteLine(typeof(ClassB).IsSubclassOf(typeof(ClassA))); // True Console.WriteLine(typeof(ClassB).IsSubclassOf(typeof(ClassB))); // False Console.WriteLine(typeof(ClassB).IsSubclassOf(typeof(ClassC))); // False Console.WriteLine(typeof(ClassC).IsSubclassOf(typeof(ClassA))); // True Console.WriteLine(typeof(ClassC).IsSubclassOf(typeof(ClassB))); // True
这个方法不能用于判断是否是某个接口
The IsSubclassOf method cannot be used to determine whether an interface derives from another interface, or whether a class implements an interface. IsSubClassOf 这个方法不能用来确定一个接口继承自另一个接口,也不能确定一个类实现了某一个接口
例如:
public interface ID { } public interface IE : ID { } public class ClassD : ID { } ... Console.WriteLine(typeof(ClassD).IsSubclassOf(typeof(ID))); // False Console.WriteLine(typeof(IE).IsSubclassOf(typeof(ID))); // False
对于泛型类又是怎么样的呢,看下面的示例:
public class ClassF<T> { } public class ClassG<T> : ClassF<T> { } public class ClassH : ClassF<int> { } // no type constraint, no good Console.WriteLine(typeof(ClassG<>).IsSubclassOf(typeof(ClassF<>))); // False // no covariance support here Console.WriteLine(typeof(string).IsSubclassOf(typeof(object))); // True Console.WriteLine(typeof(ClassG<string>).IsSubclassOf(typeof(ClassF<object>))); // False // type constraint has to match Console.WriteLine(typeof(ClassG<int>).IsSubclassOf(typeof(ClassF<int>))); // True Console.WriteLine(typeof(ClassH).IsSubclassOf(typeof(ClassF<int>))); // True Console.WriteLine(typeof(ClassH).IsSubclassOf(typeof(ClassF<long>))); // False
IsAssignableFrom
MSDN上的解释如下:
Determines whether an instance of the current Type can be assigned from an instance of the specified Type. 确定是否可以将指定的类型实例赋值给当前类型的实例
IsAssignableFrom方法和操作符的工作方式基本相同,它做了一个简单的赋值兼容性测试,检查a类型的变量是否可以赋值给b类型的变量。与IsSubClassOf方法不同的是,这个方法适用于接口之间的检查。记住:如果typeof(B).IsSubclassOf(typeof(A))为true,那么typeof(A).IsAssignableFrom(typeof(B))也为true。
Console.WriteLine(typeof(IA).IsAssignableFrom(typeof(IB))); // True Console.WriteLine(typeof(IA).IsAssignableFrom(typeof(IA))); // True Console.WriteLine(typeof(IB).IsAssignableFrom(typeof(IA))); // False Console.WriteLine(typeof(IA).IsAssignableFrom(typeof(ClassA))); // True Console.WriteLine(typeof(ClassA).IsAssignableFrom(typeof(ClassB))); // True
同样的,对于泛型之间的判断
// no type constraint, still no good Console.WriteLine(typeof(ClassF<>).IsAssignableFrom(typeof(ClassG<>))); // False // note: whilst you cant specify generic variance on the class definition you can do it on the // interface, e.g. IEnumerable<out T>, so were able to do the following test Console.WriteLine(typeof(object).IsAssignableFrom(typeof(string))); // True Console.WriteLine(typeof(IEnumerable<object>).IsAssignableFrom(typeof(IEnumerable<string>))); // True
性能开销
通常,反射对于性能来说都是一项昂贵的开销,如果必须在代码中执行大量反射,应该要注意潜在的性能问题。