读经典——《CLR via C#》(Jeffrey Richter著) 笔记_元数据
1.元数据简介
全称:metadata
属性:数据表集合
产地:面向 CLR 的编译器在托管模块中生成
2.元数据内部结构及与托管模块的关系
【概述】
托管模块中包含着元数据,元数据是由一组数据表组成的。其中一些数据表描述了模块中定义的内容
【关系图】

3.元数据的用途
- 编译时,元数据消除了对本地 C/C++ 头和库文件的需求,因为在负责实现类型/成员的 IL 代码文件中,已包含和引用的类型/成员有关的全部信息。编译器可直接从托管模块读取元数据。
- Microsoft Visual Studio 使用元数据帮助你写代码。它的“智能感知”(IntelliSense)技术可以解析元数据,指出一个类型提供了哪些方法、属性、事件和字段。如果是一个方法,还能指出该方法需要什么参数。
- CLR 的代码验证过程使用元数据确保代码只执行“类型安全”的操作。
- 元数据允许将一个对象的字段序列化到一个内存块中,将其发送给另一台机器,然后反序列化,在远程机器上重建对象的状态。
- 元数据允许垃圾回收期跟踪对象的生存期。垃圾回收器能判断任何对象的类型,并从元数据知道哪个对象中的哪些字段引用了其他对象。
4.第二章元数据内容
元数据是一个二进制数据块,由几个表构成。这些表分为三个类别:定义表(definition table)、引用表(reference table)和清单表(manifest table)。
【常用的定义表】
- ModuleDef
总是包含一个用于标识模块的记录项。在这个记录项中,包含模块的文件名和扩展名(不含路径),以及一个模块版本ID(采用由编译器创建的GUID的形式)。这允许自由地重命名文件,同事保留其原始名称记录。然而,不建议重命名,它会妨碍CLR在运行时正确定位程序集。
- TypeDef
模块中定义的每个类型都在这个定义表中有一个对应的记录项。每个记录项都包含类型的名称、基类型、一些标志(public、private等)以及一些索引,这些索引指向该类型在MethodDef表中拥有的方法、在FieldDef表中拥有的字段、在PropertyDef表中拥有的属性以及在EventDef表中拥有的事件。
- MethodDef
模块中定义的每个方法都在这个定义表中有一个对应的记录项。每个记录项都包含方法的名称、一些标志(private、public、virtual、abstract、static、final等)、签名以及该方法的IL代码在模块中的偏移量。每个记录项还引用了ParamDef表中的一个记录项,后者包括与方法参数相关的更多信息。
- FieldDef
模块中定义的每个字段都在这个定义表中有一个对应的记录项。每个记录项包括标志(public、private等)、类型和名称。
- ParamDef
模块中定义的每个参数都在这个定义表中有一个对应的记录项。每个记录项都包含标志(in,out,retval等)、类型和名称。
- PropertyDef
模块中定义的每个属性都在这个定义表中有一个对应的记录项。每个记录项都包含标志、类型和名称。
- EventDef
模块中定义的每个事件都在这个定义表中有一个对应的记录项。每个记录项都包含标志和名称。
【常用的引用表】
- AssemblyRef
模块中引用的每个程序集在这个表中都有一个对应的记录项。每个记录项都包含绑定到程序集所需的信息:程序集名称(不含路径和扩展名)、版本号、语言文化(culture)以及公钥标记(根据发布者的公钥生成的一个小的哈希值,它标识了所引用的程序集的发布者)。在每个记录项中,还包含一些标志(flag)和一个哈希值。这个哈希值本应作为所引用的程序集的二进制数据的一个校验和来使用。但是,目前的CLR完全忽略这个哈希值,未来的CLR可能同样如此。
- ModuleRef
当前模块引用的类型可能是由别的PE模块实现的,所有那些模块在这个表中都有一个对应的记录项。每个记录项都包含模块的文件名和扩展名(不含路径)。在当前的调用程序集中,可能是别的模块实现了你需要的类型,这个表的作用便是建立同那些类型的绑定关系。
- TypeRef
模块引用的每个类型在这个表中都有一个对应的记录项。每个记录项都包含类型的名称和一个引用(指向类型的位置)。如果类型是在另一类型中实现的,引用指向的就是一个TypeRef记录项。如果类型是在同一个模块中实现的,引用指向的就是一个ModuleDef记录项。如果类型是在调用程序集内部的另一个模块中实现的,引用指向的就是一个ModuleRef记录项。如果类型是在不同的程序集中实现的,引用指向的就是一个AssemblyRef记录项。
- MemeberRef
模块引用的每个成员(字段、方法,以及属性方法和事件方法)都在这个表中有一个对应的记录项。每个记录项都包含成员的名称和签名,并指向对成员进行定义的那个类型的TypeRef记录项。
【常用清单表】
- AssemblyDef
如果该模块标识的是一个程序集,就在这个元数据表中包含单个记录项。该记录项列出了程序集名称(不含路径和扩展名)、版本(major,minor,build和revision)、语言文化(culture)、一些标志(flag)、哈希算法以及发布者的公钥(可为null)
- FileDef
作为程序集一部分的每个PE文件和资源文件在这个表中都有一个对应的记录项(包含清单本身的那个文件除外,它在AssemblyDef表中显示为单一记录项)。在每个记录相中,都包含文件名和扩展名(不含路径)、哈希值和一些标志(flags)。假如该程序集只包含它自己的文件,FileDef表中将无记录项。
- ManifestResourceDef
作为程序集一部分的每个资源在这个表中都有一个对应的记录项。记录项中包含资源的名称、一些标志(如果程序集外部可见,就为public;否则为private)以及FileDef表的一个索引(指出资源包含在哪个文件中)。如果资源不是一个独立文件(比如.jpg或者.gif文件),那么资源就是包含在PE文件中的一个流。对于嵌入的资源,这个记录项还包含一个偏移量,指出了资源流在PE文件中的起始位置。
- ExportedTypesDef
从程序集的所有PE模块中导出的每个public类型在这个表中都有一个对应的记录项。记录项中包含类型的名称、FileDef表的一个索引(指出类型是由该程序集的哪个文件实现的)以及TypeDef表的一个索引。注意,为了节省文件空间,从包含清单的文件导出的类型不在这个表中重复,以为可以使用元数据的TypeDef表来获取类型信息。
读经典——《CLR via C#》(Jeffrey Richter著) 笔记_元数据的更多相关文章
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_发布者策略控制
在 读经典——<CLR via C#>(Jeffrey Richter著) 笔记_高级管理控制(配置)中,是由程序集的发布者将程序集的一个新版本发送给管理员,后者安装程序集,并手动编辑应用 ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_通过ILDasm.exe查看编译器如何将类型及其成员编译成元数据
[实例代码] using System; public sealed class SomeType //-------------1 { //嵌套类 private class SomeNestedT ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_基元类型(二)
[基元类型推荐] 推荐直接使用 FCL 类型. [理由] 编码时不至于困惑string与String的使用.由于C#的stirng(一个关键字)直接映射到System.String(一个 FCL 类型 ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_基元类型(一)
[概念] 编译器直接支持的数据类型 [C#基元类型与对应的 FCL 类型] C#基元类型 FCL 类型 说明 sbyte System.Sbyte 有符号8位值 byte System.Byte 无符 ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_高级管理控制(配置)
一个应用程序的XML配置文件示例: <?xml version="1.0"?> <configuration> <runtime> <as ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_运行时解析类型引用
public sealed class Program{ public static void Main() { System.Console.WriteLine("Hi"); } ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_方法执行
[前言] 方法执行前,CLR 会检测方法内代码引用的所有类型.同时 CLR 会分配一个内部数据结构,用来管理对所有引用的类型的访问. 首次执行方法时,托管程序集会把 IL 转换成本地 CPU 指令,并 ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_友元程序集
[应用场景] 程序集A访问程序集B定义的Internal访问类型的类的成员. [使用方式] 在构建程序集B的时候,引入System.Runtime.CompilerServices,以此来添加Inte ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_类型的各种成员
[Class中,可能包含的成员] 常量, 字段, 实例构造器, 类型构造器, 方法, 操作符重载, 转换操作符, 属性, 事件, 类型(Class)
随机推荐
- maven依赖scope配置项讲解
我们在使用Maven配置依赖项的时候,常常只会配置Maven的坐标以及版本信息就可以了,但我们看其他人的工程代码的时候常常会见到有个scope配置项,今天就来分别介绍下这个配置下几个类别的作用. &l ...
- BitmapCutter.Core 引用步骤
1 将BitmapCutter.Core项目或者dll引用到需要的项目底下. 2 前台页面 <img id="imgPreview1" title="点击上传图片& ...
- js语法和数据类型
基础知识(Basics) JavaScript 的很多语法借鉴自 Java,但也受 Awk,Perl 和 Python 影响. JavaScript 是大小写敏感的,使用 Unicode 字符集. 在 ...
- ListView---复杂的listview显示
1 . 初始化数据 private void fillData() { ll_loading.setVisibility(View.VISIBLE); // 显示进度 new Thread() { p ...
- Executor线程池
Executor线程池框架: 使用线程池的优点: 1.重用存在的线程 2.减少对象创建.消亡的开销 3.性能佳 4.可有效控制最大并发线程数,提高系统资源的使用率 5.避免过多资源竞争,避免堵塞 6. ...
- iOS 添加Empty Application模板
在Apple最新的XCode6.x中没有了Empty Application模板,好在XCode可以添加模板,而且可以自定义模板. 首先可以到XCode5.x中复制 Empty Application ...
- 51NOD1052 最大M字段和
传送门 分析 一眼看去我们自然会想到dp[i][j][k]表示区间[i,j]中选k个子段的最大值.然后我们考虑降去一维.我们设dp[i][j]表示考虑了前i个数,在选了a[i]的情况下共有j个子段的最 ...
- Leafletjs学习教程和相关代码整理
一.Leaflet简介 官方网站:http://leafletjs.com/ 官网上的api和例子大家多看看,多学习学习. Lefalet 是一个为建设移动设备友好的互动地图,而开发的现代的.开源的 ...
- markdown编辑器使用教程
网上的资料很多,我收集整理学习下. 我是下划线 *** 我是标题 我也是标题 ewq着重ewqe 列表1 列表2 我也是 我也是 有序列表 有序列表 //我是代码 int x=0; int y=x; ...
- 动态变更Repeater控件HeaderTemplate列名
本博文,Insus.NET教你动态实现变更Repeater控件HeaderTemplate列名.一般情况之下,是不需要动态变更,只有动态有Repeater控件不变情况之下,来显示多种数据源进行绑定.这 ...