• 读经典——《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表来获取类型信息。

  • 相关阅读:
    JavaScript (三) js的基本语法
    JavaScript (二) js的基本语法
    JavaScript (一) js的介绍及基本语法变量
    Spring事务管理
    python静态方法、类方法
    python多继承
    python面向对象
    python模块(4)
    python模块(3)
    python模块(2)
  • 原文地址:https://www.cnblogs.com/lishidefengchen/p/4348511.html
Copyright © 2020-2023  润新知