浅谈.NET框架中反射的内部机制
在.NET众多的特性中,可以说反射式.NET框架最独特的一个特性,这一点在其他框架中没有对应的概念。反射在.NET中的地位也是非常重要的,正是存在元素据等信息,才构成了.NET系统运行的基础。
需要说明的是反射在实际开发中的运用,远远没有.NET框架自身对反射的应用多,某种程度上,理解反射的原理和机制,比能够使用反射更为重要,因为能够帮助程序员更透彻的理解.NET的机制和原理。。
在.NET框架中,反射提供了一种动态分析、创建和调用的机制。在.NET框架中,一个系统可以由多个程序集组成,一个程序集可以包含多个模块,而一个模块中会有很多类型,每个类型可以包含字段和方法,方法又可以包含输入参数和输出参数、特性等多种信息。在其他技术框架中,使用一个模块往往需要在编码时彻底地了解其对外的接口,而在.NET中,反射机制使得动态分析程序集并且使用其中的类型和方法称为了可能。
这里DebugLZQ再简单介绍.NET程序集的元数据概念。元数据,就是描述数据的数据。在CLR中,元数据就是对一个模块定义或引用的所有东西的描述系统。因为CLR编程系统是面向对象的,所以元素据描述的东西就是类型和他们的成员以及伴随而来的特性、属性和联系。元数据正是反射机制能够运作的基石,和COM只记录公共接口不同,元素据存储了类型内部的所有信息,这也就意味着,程序可以动态地得到整个程序集的内部结构(注意:这里说的是能够得到,但并不意味着可以访问。对程序集的访问仍然受到访问级别的控制)。
为了更直接的体会元素据的描述,下面写一段简单的测试代码,并且查看它生成程序集的元素据。代码如下:
using System; using System.Reflection; namespace 简单程序集 { /// <summary> /// 构建一个包含私有成员、特性、方法的简单类型 /// </summary> [Serializable ] class Program { private string _MyString; public Program(string mystring) { _MyString = mystring; } public override string ToString() { return _MyString; } private static void ShowMemberInfo() { var assems = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly ass in assems) { foreach (Type t in ass.GetTypes()) { foreach (MemberInfo mi in t.GetMembers()) { Console.WriteLine("Name:{0}, Type:{1}", mi.Name, mi.MemberType.ToString()); } } } } static void Main(string[] args) { Console.WriteLine("Sample Assembly by DebugLZQ."); ShowMemberInfo(); Console.ReadKey(); } } }
编译该程序集后,默认生成一个.exe的程序集。利用vs自带的ildasm工具来查看一下这个程序集的元素据(快捷键Ctrl + M)。如下:
=========================================================== MVID : {9419D95D-928D-4142-8803-99745DCC631E} =========================================================== Global functions ------------------------------------------------------- Global fields ------------------------------------------------------- Global MemberRefs ------------------------------------------------------- TypeDef #1 (02000002) ------------------------------------------------------- Flags : [NotPublic] [AutoLayout] [Class] [Serializable] [AnsiClass] [BeforeFieldInit] (00102000) Extends : 01000001 [TypeRef] System.Object Field #1 (04000001) ------------------------------------------------------- Field Name: _MyString (04000001) Flags : [Private] (00000001) CallCnvntn: [FIELD] Field type: String Method #1 (06000001) ------------------------------------------------------- MethodName: .ctor (06000001) Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] (00001886) RVA : 0x00002050 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String 1 Parameters (1) ParamToken : (08000001) Name : mystring flags: [none] (00000000) Method #2 (06000002) ------------------------------------------------------- MethodName: ToString (06000002) Flags : [Public] [Virtual] [HideBySig] [ReuseSlot] (000000c6) RVA : 0x00002064 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: String No arguments. Method #3 (06000003) ------------------------------------------------------- MethodName: ShowMemberInfo (06000003) Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091) RVA : 0x0000207c ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] ReturnType: Void No arguments. Method #4 (06000004) [ENTRYPOINT] ------------------------------------------------------- MethodName: Main (06000004) Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091) RVA : 0x00002135 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] ReturnType: Void 1 Arguments Argument #1: SZArray String 1 Parameters (1) ParamToken : (08000002) Name : args flags: [none] (00000000) TypeRef #1 (01000001) ------------------------------------------------------- Token: 0x01000001 ResolutionScope: 0x23000001 TypeRefName: System.Object MemberRef #1 (0a000012) ------------------------------------------------------- Member: (0a000012) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. MemberRef #2 (0a000019) ------------------------------------------------------- Member: (0a000019) ToString: CallCnvntn: [DEFAULT] hasThis ReturnType: String No arguments. TypeRef #2 (01000002) ------------------------------------------------------- Token: 0x01000002 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyTitleAttribute MemberRef #1 (0a000001) ------------------------------------------------------- Member: (0a000001) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #3 (01000003) ------------------------------------------------------- Token: 0x01000003 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyDescriptionAttribute MemberRef #1 (0a000002) ------------------------------------------------------- Member: (0a000002) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #4 (01000004) ------------------------------------------------------- Token: 0x01000004 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyConfigurationAttribute MemberRef #1 (0a000003) ------------------------------------------------------- Member: (0a000003) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #5 (01000005) ------------------------------------------------------- Token: 0x01000005 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyCompanyAttribute MemberRef #1 (0a000004) ------------------------------------------------------- Member: (0a000004) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #6 (01000006) ------------------------------------------------------- Token: 0x01000006 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyProductAttribute MemberRef #1 (0a000005) ------------------------------------------------------- Member: (0a000005) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #7 (01000007) ------------------------------------------------------- Token: 0x01000007 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyCopyrightAttribute MemberRef #1 (0a000006) ------------------------------------------------------- Member: (0a000006) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #8 (01000008) ------------------------------------------------------- Token: 0x01000008 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyTrademarkAttribute MemberRef #1 (0a000007) ------------------------------------------------------- Member: (0a000007) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #9 (01000009) ------------------------------------------------------- Token: 0x01000009 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyCultureAttribute MemberRef #1 (0a000008) ------------------------------------------------------- Member: (0a000008) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #10 (0100000a) ------------------------------------------------------- Token: 0x0100000a ResolutionScope: 0x23000001 TypeRefName: System.Runtime.InteropServices.ComVisibleAttribute MemberRef #1 (0a000009) ------------------------------------------------------- Member: (0a000009) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: Boolean TypeRef #11 (0100000b) ------------------------------------------------------- Token: 0x0100000b ResolutionScope: 0x23000001 TypeRefName: System.Runtime.InteropServices.GuidAttribute MemberRef #1 (0a00000a) ------------------------------------------------------- Member: (0a00000a) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #12 (0100000c) ------------------------------------------------------- Token: 0x0100000c ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyVersionAttribute MemberRef #1 (0a00000b) ------------------------------------------------------- Member: (0a00000b) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #13 (0100000d) ------------------------------------------------------- Token: 0x0100000d ResolutionScope: 0x23000001 TypeRefName: System.Reflection.AssemblyFileVersionAttribute MemberRef #1 (0a00000c) ------------------------------------------------------- Member: (0a00000c) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #14 (0100000e) ------------------------------------------------------- Token: 0x0100000e ResolutionScope: 0x23000001 TypeRefName: System.Runtime.Versioning.TargetFrameworkAttribute MemberRef #1 (0a00000d) ------------------------------------------------------- Member: (0a00000d) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: String TypeRef #15 (0100000f) ------------------------------------------------------- Token: 0x0100000f ResolutionScope: 0x23000001 TypeRefName: System.Diagnostics.DebuggableAttribute MemberRef #1 (0a00000e) ------------------------------------------------------- Member: (0a00000e) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: ValueClass DebuggingModes TypeRef #16 (01000010) ------------------------------------------------------- Token: 0x01000010 ResolutionScope: 0x0100000f TypeRefName: DebuggingModes TypeRef #17 (01000011) ------------------------------------------------------- Token: 0x01000011 ResolutionScope: 0x23000001 TypeRefName: System.Runtime.CompilerServices.CompilationRelaxationsAttribute MemberRef #1 (0a00000f) ------------------------------------------------------- Member: (0a00000f) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void 1 Arguments Argument #1: I4 TypeRef #18 (01000012) ------------------------------------------------------- Token: 0x01000012 ResolutionScope: 0x23000001 TypeRefName: System.Runtime.CompilerServices.RuntimeCompatibilityAttribute MemberRef #1 (0a000010) ------------------------------------------------------- Member: (0a000010) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. TypeRef #19 (01000013) ------------------------------------------------------- Token: 0x01000013 ResolutionScope: 0x23000001 TypeRefName: System.SerializableAttribute MemberRef #1 (0a000011) ------------------------------------------------------- Member: (0a000011) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. TypeRef #20 (01000014) ------------------------------------------------------- Token: 0x01000014 ResolutionScope: 0x23000001 TypeRefName: System.AppDomain MemberRef #1 (0a000013) ------------------------------------------------------- Member: (0a000013) get_CurrentDomain: CallCnvntn: [DEFAULT] ReturnType: Class System.AppDomain No arguments. MemberRef #2 (0a000014) ------------------------------------------------------- Member: (0a000014) GetAssemblies: CallCnvntn: [DEFAULT] hasThis ReturnType: SZArray Class System.Reflection.Assembly No arguments. TypeRef #21 (01000015) ------------------------------------------------------- Token: 0x01000015 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.Assembly MemberRef #1 (0a000015) ------------------------------------------------------- Member: (0a000015) GetTypes: CallCnvntn: [DEFAULT] hasThis ReturnType: SZArray Class System.Type No arguments. TypeRef #22 (01000016) ------------------------------------------------------- Token: 0x01000016 ResolutionScope: 0x23000001 TypeRefName: System.Type MemberRef #1 (0a000016) ------------------------------------------------------- Member: (0a000016) GetMembers: CallCnvntn: [DEFAULT] hasThis ReturnType: SZArray Class System.Reflection.MemberInfo No arguments. TypeRef #23 (01000017) ------------------------------------------------------- Token: 0x01000017 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.MemberInfo MemberRef #1 (0a000017) ------------------------------------------------------- Member: (0a000017) get_Name: CallCnvntn: [DEFAULT] hasThis ReturnType: String No arguments. MemberRef #2 (0a000018) ------------------------------------------------------- Member: (0a000018) get_MemberType: CallCnvntn: [DEFAULT] hasThis ReturnType: ValueClass System.Reflection.MemberTypes No arguments. TypeRef #24 (01000018) ------------------------------------------------------- Token: 0x01000018 ResolutionScope: 0x23000001 TypeRefName: System.Reflection.MemberTypes TypeRef #25 (01000019) ------------------------------------------------------- Token: 0x01000019 ResolutionScope: 0x23000001 TypeRefName: System.Console MemberRef #1 (0a00001a) ------------------------------------------------------- Member: (0a00001a) WriteLine: CallCnvntn: [DEFAULT] ReturnType: Void 3 Arguments Argument #1: String Argument #2: Object Argument #3: Object MemberRef #2 (0a00001b) ------------------------------------------------------- Member: (0a00001b) WriteLine: CallCnvntn: [DEFAULT] ReturnType: Void 1 Arguments Argument #1: String MemberRef #3 (0a00001c) ------------------------------------------------------- Member: (0a00001c) ReadKey: CallCnvntn: [DEFAULT] ReturnType: ValueClass System.ConsoleKeyInfo No arguments. TypeRef #26 (0100001a) ------------------------------------------------------- Token: 0x0100001a ResolutionScope: 0x23000001 TypeRefName: System.ConsoleKeyInfo Signature #1 (0x11000001) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 1 Arguments Argument #1: String Signature #2 (0x11000002) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 11 Arguments Argument #1: SZArray Class System.Reflection.Assembly Argument #2: Class System.Reflection.Assembly Argument #3: Class System.Type Argument #4: Class System.Reflection.MemberInfo Argument #5: SZArray Class System.Reflection.Assembly Argument #6: I4 Argument #7: SZArray Class System.Type Argument #8: I4 Argument #9: SZArray Class System.Reflection.MemberInfo Argument #10: I4 Argument #11: Boolean Assembly ------------------------------------------------------- Token: 0x20000001 Public Key : Hash Algorithm : 0x00008004 Version: 1.0.0.0 Major Version: 0x00000001 Minor Version: 0x00000000 Build Number: 0x00000000 Revision Number: 0x00000000 Locale: <null> Flags : [none] (00000000) CustomAttribute #1 (0c000001) ------------------------------------------------------- CustomAttribute Type: 0a000001 CustomAttributeName: System.Reflection.AssemblyTitleAttribute :: instance void .ctor(class System.String) Length: 20 Value : 01 00 0f e7 ae 80 e5 8d 95 e7 a8 8b e5 ba 8f e9 > < : 9b 86 00 00 > < ctor args: ("简单程序集") CustomAttribute #2 (0c000002) ------------------------------------------------------- CustomAttribute Type: 0a000002 CustomAttributeName: System.Reflection.AssemblyDescriptionAttribute :: instance void .ctor(class System.String) Length: 5 Value : 01 00 00 00 00 > < ctor args: ("") CustomAttribute #3 (0c000003) ------------------------------------------------------- CustomAttribute Type: 0a000003 CustomAttributeName: System.Reflection.AssemblyConfigurationAttribute :: instance void .ctor(class System.String) Length: 5 Value : 01 00 00 00 00 > < ctor args: ("") CustomAttribute #4 (0c000004) ------------------------------------------------------- CustomAttribute Type: 0a000004 CustomAttributeName: System.Reflection.AssemblyCompanyAttribute :: instance void .ctor(class System.String) Length: 5 Value : 01 00 00 00 00 > < ctor args: ("") CustomAttribute #5 (0c000005) ------------------------------------------------------- CustomAttribute Type: 0a000005 CustomAttributeName: System.Reflection.AssemblyProductAttribute :: instance void .ctor(class System.String) Length: 20 Value : 01 00 0f e7 ae 80 e5 8d 95 e7 a8 8b e5 ba 8f e9 > < : 9b 86 00 00 > < ctor args: ("简单程序集") CustomAttribute #6 (0c000006) ------------------------------------------------------- CustomAttribute Type: 0a000006 CustomAttributeName: System.Reflection.AssemblyCopyrightAttribute :: instance void .ctor(class System.String) Length: 23 Value : 01 00 12 43 6f 70 79 72 69 67 68 74 20 c2 a9 20 > Copyright < : 20 32 30 31 32 00 00 > 2012 < ctor args: ("Copyright © 2012") CustomAttribute #7 (0c000007) ------------------------------------------------------- CustomAttribute Type: 0a000007 CustomAttributeName: System.Reflection.AssemblyTrademarkAttribute :: instance void .ctor(class System.String) Length: 5 Value : 01 00 00 00 00 > < ctor args: ("") CustomAttribute #8 (0c000008) ------------------------------------------------------- CustomAttribute Type: 0a000009 CustomAttributeName: System.Runtime.InteropServices.ComVisibleAttribute :: instance void .ctor(bool) Length: 5 Value : 01 00 00 00 00 > < ctor args: ( <can not decode> ) CustomAttribute #9 (0c000009) ------------------------------------------------------- CustomAttribute Type: 0a00000a CustomAttributeName: System.Runtime.InteropServices.GuidAttribute :: instance void .ctor(class System.String) Length: 41 Value : 01 00 24 66 61 66 61 61 65 66 38 2d 33 31 32 34 > $fafaaef8-3124< : 2d 34 36 34 39 2d 62 34 34 64 2d 37 65 63 35 35 >-4649-b44d-7ec55< : 61 39 35 32 39 35 63 00 00 >a95295c < ctor args: ("fafaaef8-3124-4649-b44d-7ec55a95295c") CustomAttribute #10 (0c00000a) ------------------------------------------------------- CustomAttribute Type: 0a00000c CustomAttributeName: System.Reflection.AssemblyFileVersionAttribute :: instance void .ctor(class System.String) Length: 12 Value : 01 00 07 31 2e 30 2e 30 2e 30 00 00 > 1.0.0.0 < ctor args: ("1.0.0.0") CustomAttribute #11 (0c00000b) ------------------------------------------------------- CustomAttribute Type: 0a00000d CustomAttributeName: System.Runtime.Versioning.TargetFrameworkAttribute :: instance void .ctor(class System.String) Length: 101 Value : 01 00 29 2e 4e 45 54 46 72 61 6d 65 77 6f 72 6b > ).NETFramework< : 2c 56 65 72 73 69 6f 6e 3d 76 34 2e 30 2c 50 72 >,Version=v4.0,Pr< : 6f 66 69 6c 65 3d 43 6c 69 65 6e 74 01 00 54 0e >ofile=Client T < : 14 46 72 61 6d 65 77 6f 72 6b 44 69 73 70 6c 61 > FrameworkDispla< : 79 4e 61 6d 65 1f 2e 4e 45 54 20 46 72 61 6d 65 >yName .NET Frame< : 77 6f 72 6b 20 34 20 43 6c 69 65 6e 74 20 50 72 >work 4 Client Pr< : 6f 66 69 6c 65 >ofile < ctor args: (".NETFramework,Version=v4.0,Profile=Client") CustomAttribute #12 (0c00000c) ------------------------------------------------------- CustomAttribute Type: 0a00000e CustomAttributeName: System.Diagnostics.DebuggableAttribute :: instance void .ctor(value class DebuggingModes) Length: 8 Value : 01 00 07 01 00 00 00 00 > < ctor args: ( <can not decode> ) CustomAttribute #13 (0c00000d) ------------------------------------------------------- CustomAttribute Type: 0a00000f CustomAttributeName: System.Runtime.CompilerServices.CompilationRelaxationsAttribute :: instance void .ctor(int32) Length: 8 Value : 01 00 08 00 00 00 00 00 > < ctor args: (8) CustomAttribute #14 (0c00000e) ------------------------------------------------------- CustomAttribute Type: 0a000010 CustomAttributeName: System.Runtime.CompilerServices.RuntimeCompatibilityAttribute :: instance void .ctor() Length: 30 Value : 01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78 > T WrapNonEx< : 63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01 >ceptionThrows < ctor args: () AssemblyRef #1 (23000001) ------------------------------------------------------- Token: 0x23000001 Public Key or Token: b7 7a 5c 56 19 34 e0 89 Name: mscorlib Version: 4.0.0.0 Major Version: 0x00000004 Minor Version: 0x00000000 Build Number: 0x00000000 Revision Number: 0x00000000 Locale: <null> HashValue Blob: Flags: [none] (00000000) User Strings ------------------------------------------------------- 70000001 : (18) L"Name:{0}, Type:{1}" 70000027 : (28) L"Sample Assembly by DebugLZQ." Coff symbol name overhead: 0 =========================================================== =========================================================== ===========================================================
纵观整个元素据表,大致可以分为定义表、引用表、指针表、堆等:
- 定义表,描述了源代码中定义的类型和成员信息,主要包括:TypeDef、MehodDef、FieldDef、ModuleDef、PropertyDef等。
- 引用表,描述了源代码中引用的类型和成员信息,引用元素可以是同一程序集的其他模块,也可以是不同程序集的模块,主要包括:AssemblyRef、TypeRef、ModuleRef、MethodsRef等。
- 指针表,使用指针表引用未知代码,主要包括:MethodPtr、FieldPtr、ParamPtr等。
- 堆,以stream的形式保存的信息堆,主要包括:#String、#Blob、#US、#GUIDe等。
如前文所述,我们以ILDasm.exe可以通过反编译的方式,通过执行Ctrl+M快捷键来获取该程序集所使用的MetaData信息列表,在.NET中每个模块包含了44个CLR元数据表,如下:
表记录 | 元数据表 | 说明 |
0(0) | ModuleDef | 描述当前模块 |
1(0x1) | TypeRef | 描述引用Type,为每个引用到类型保存一条记录 |
2(0x2) | TypeDef | 描述Type定义,每个Type将在TypeDef表中保存一条记录 |
3(0x3) | FieldPtr | 描述字段指针,定义类的字段时的中间查找表 |
4(0x4) | FieldDef | 描述字段定义 |
5(0x5) | MethodPtr | 描述方法指针,定义类的方法时的中间查找表 |
6(0x6) | MethodDef | 描述方法定义 |
7(0x7) | ParamPtr | 描述参数指针,定义类的参数时的中间查找表 |
8(0x8) | ParamDef | 描述方法的参数定义 |
9(0x9) | InterfaceImpl | 描述有哪些类型实现了哪些接口 |
10(0xa) | MemberRef | 描述引用成员的情况,引用成员可以是方法、字段还有属性。 |
11(0xb) | Constant | 描述了参数、字段和属性的常数值 |
12(0xc) | CustomAttribute | 描述了特性的定义 |
13(0xd) | FieldMarshal | 描述了与非托管代码交互时,参数和字段的传递方式。 |
14(0xe) | DeclSecurity | 描述了对于类、方法和程序集的安全性 |
15(0xf) | ClassLayout | 描述类加载时的布局信息 |
16(0x10) | FieldLayout | 描述单个字段的偏移或序号 |
17(0x11) | StandAloneSig | 描述未被任何其他表引用的签名 |
18(0x12) | EventMap | 描述类的事件列表 |
19(0x13) | EventPtr | 描述了事件指针,定义事件时的中间查找表 |
20(0x14) | Event | 描述事件 |
21(0x15) | PropertyMap | 描述类的属性列表 |
22(0x16) | PropertyPtr | 描述了属性指针,定义类的属性时的中间查找表 |
23(0x17) | Property | 描述属性 |
24(0x18) | MethodSemantics | 描述事件、属性与方法的关联 |
25(0x19) | MethodImpl | 描述方法的实现 |
26(0x1a) | ModuleRef | 描述外部模块的引用 |
27(0x1b) | TypeSpec | 描述了对TypeDef或者TypeRef的说明 |
28(0x1c) | ImplMap | 描述了程序集使用的所有非托管代码的方法 |
29(0x1d) | FieldRVA | 字段表的扩展,RVA给出了一个字段的原始值位置 |
30(0x1e) | ENCLog | 描述在Edit-And-Continue模式中哪些元数据被修改过 |
31(0x1f) | ENCMap | 描述在Edit-And-Continue模式中的映射 |
32(0x20) | Assembly | 描述程序集定义 |
33(0x21) | AssemblyProcessor | 未使用 |
34(0x22) | AssemblyOS | 未使用 |
35(0x23) | AssemblyRef | 描述引用的程序集 |
36(0x24) | AssemblyRefProcessor | 未使用 |
37(0x25) | AssemblyRefOS | 未使用 |
38(0x26) | File | 描述外部文件 |
39(0x27) | ExportedType | 描述在同一程序集但不同模块,有哪些类型 |
40(0x28) | ManifestResource | 描述资源信息 |
41(0x29) | NestedClass | 描述嵌套类型定义 |
42(0x2a) | GenericParam | 描述了泛型类型定义或者泛型方法定义所使用的泛型参数 |
43(0x2b) | MethodSpec | 描述泛型方法的实例化 |
44(0x2c) | GenericParamConstraint | 描述了每个泛型参数的约束 |
然后是6个命名堆:
堆 |
说明 |
#String | 一个AscII string数组,被元数据表所引用,来表示方法名、字段名、类名、变量名以及资源相关字符串,但不包含string literals。 |
#Blob | 包含元数据引用的二进制对象,但不包含用户定义对象 |
#US | 一个unicode string数组,包含了定义在代码中的字符串(string literals),这些字符串可以直接由ldstr指令加载获取, |
#GUID | 保存了128byte的GUID值,由元数据表引用 |
#~ | 一个特殊堆,包含了所有的元数据表,会引用其他的堆。 |
#- | 一个未压缩的#~堆。除了#-堆,其他堆都是压缩的。 |
运行上面这段示例程序,能能够获得一个很长很长很长的运行时元素据信息。结果如下:
正如以上分析的,程序集的内部结构在元数据中一览无余,也可在运行时动态获得元素据的相关信息,因为元素据的数据结构是标准固定的,这使得外部代码可以轻松地动态获得程序集的信息并使用。这也就实现了.NET中最独特的特性:反射。
DebugLZQ:反射的本质在于读取元数据来分析模块或者程序集,而并不规定读取的方法。同时,.NET提供了多个类型方便程序员分析元数据,但反射机制概念和这些类型的使用并不绑定。欢迎批评指正!
【请点击下面的“绿色通道”---“关注DebugLZQ”,共同交流进步~】