元数据表
程序集的元数据是用一系列表来存储的。生成一个程序集或者模块时,编译器会创建一个类型定义表、一个字段定义表、一个方法定义表以及其他表
反射的性能
- 反射会造成编译时无法保证类型安全性。由于反射要严重依赖字符串,所以会丧失编译时的类型安全性。
- 反射速度慢。使用反射时,类型及其成员的名称在编译时未知。要使用字符串名称表示每个类型及其成员,以便在运行时发现他们。也就是说,使用System.Reflection命名空间的类型扫描程序集的元数据时,反射要不断的执行字符串搜索和比较。
发现类型的成员
字段、构造器、方法、属性、事件和嵌套类型都可以被定义为一个类型的成员。下图显示了这些类型的层次结构:
DeclaringType和ReflectedType(从MemberInfo派生的所有类型都通用的属性和方法)
public sealed class MyType { public override string ToString() { return null; } public void FunctionOne() { } /// <summary> /// Check if methods of MyType are DeclaringType or ReflectedType /// </summary> public void ShowIfDeclaringTypeOrReflectedType() { Type thisType = typeof(MyType); MemberInfo[] methodsInfos = thisType.GetMethods(); foreach (var item in methodsInfos) { Console.WriteLine("Member name :{0}, DeclaringType: {1}, ReflectedType: {2}", item, item.DeclaringType, item.ReflectedType); } } }
结果:
Member name :System.String ToString(), DeclaringType: TypesDemo.MyType, ReflectedType: TypesDemo.MyType
Member name :Void FunctionOne(), DeclaringType: TypesDemo.MyType, ReflectedType: TypesDemo.MyType
Member name :Void ShowIfDeclaringTypeOrReflectedType(), DeclaringType: TypesDemo.MyType, ReflectedType: TypesDemo.MyType
Member name :Boolean Equals(System.Object), DeclaringType: System.Object, ReflectedType: TypesDemo.MyType
Member name :Int32 GetHashCode(), DeclaringType: System.Object, ReflectedType: TypesDemo.MyType
Member name :System.Type GetType(), DeclaringType: System.Object, ReflectedType: TypesDemo.MyType
运行时类型
通过调用GetType方法可以知道一个实例的RuntimeType(CLR并没有暴露该类型)
public class SuperClass { } public class SubClass : SuperClass { }
// Runtime type determination SuperClass superType = new SuperClass(); SuperClass subType = new SubClass(); Console.WriteLine("superType : {0}, subType : {1} ,Type of superType equals to subType : {2} " , superType.GetType(), subType.GetType(), superType.GetType() == subType.GetType());
运行结果:
superType : TypesDemo.SuperClass, subType : TypesDemo.SubClass ,Type of superType equals to subType : False
发现类型的接口
InterfaceMapping类型
字段名称 | 数据类型 | 说明 |
TargetType | Type | 这是用于调用GetInterfaceMapping的类型,即实现了接口的类型 |
InterfaceType | Type | 传给GetInterfaceMapping的接口类型 |
InterfaceMethods | MemberInfo[] | 一个数组,它的每个元素都暴露了一个与接口的方法有关的信息 |
TargerMethods | MemberInfo[] | 一个数组,它的每个元素都暴露了由类型定义的一个方法的信息,这个方法实现了接口中对应的方法 |
internal interface IBookRetailer : IDisposable { void Purchase(); void ApplyDiscount(); } internal interface IMusicRetailer { void Purchase(); } internal sealed class MyRetailer : IBookRetailer, IMusicRetailer, IDisposable { void IBookRetailer.Purchase() { } public void ApplyDiscount() { } void IMusicRetailer.Purchase() { } public void Dispose() { } public void Purchase() { } }
class Program { static void Main(string[] args) { // Find interfaces Type t = typeof(MyRetailer); // Get all interfaces define in current assmebly. Type[] interfaces=t.FindInterfaces(TypeFilter,typeof(Program).Assembly); Console.WriteLine("MyRetailer implements the following interfaces (defined in this assmebly):"); foreach (Type i in interfaces) { Console.WriteLine("\nInterface: " + i); InterfaceMapping map = t.GetInterfaceMap(i); for (int m = 0; m < map.InterfaceMethods.Length; m++) { Console.WriteLine(" {0} is implemented by {1}", map.InterfaceMethods[m], map.TargetMethods[m]); } } } static Boolean TypeFilter(Type t, object filterCriteria) { return t.Assembly == filterCriteria; } }
运行结果:
Interface: TypesDemo.IBookRetailer
Void Purchase() is implemented by Void TypesDemo.IBookRetailer.Purchase()
Void ApplyDiscount() is implemented by Void ApplyDiscount()
Interface: TypesDemo.IMusicRetailer
Void Purchase() is implemented by Void TypesDemo.IMusicRetailer.Purchase()