《CLR via C#》笔记:第1部分 CLR基础

  1.7 C#, 3.2 游戏引擎技术
  • 本博客所总结书籍为《CLR via C#(第4版)》清华大学出版社,2021年11月第11次印刷(如果是旧版书籍或者pdf可能会出现书页对不上的情况)
  • 你可以理解为本博客为该书的精简子集,给正在学习中的人提供一个“glance”,以及对于部分专业术语或知识点给出解释/博客链接。
  • 【本博客有如下定义“Px x”,第一个代表书中的页数,第二个代表大致内容从本页第几段开始。(如果有last+x代表倒数第几段,last代表最后一段)】
  • 电子书可以在博客首页的文档-资源归档中找到,或者点击:传送门自行查找。如有能力请支持正版。(很推荐放在竖屏上阅读本电子书,这多是一件美事)
  • 作为导引,你可能需要了解以下的知识
    Mono,CLR,.net,Net Framework之间的关系:传送门

    CLR官方手册:传送门(英文警告)
    什么是CLR:传送门
    Unity的基本代码编写及其使用。
    鲁棒性:传送门

    公钥,私钥,数据签名:传送门
  • 同时建议实践与理论并行,可以找些教程边写边学。
  • 本书籍不适合零基础编程或者对class没有全面了解的人进行学习,如符合上述表征,请先阅读相关基础入门书籍。

前言

  • 我想以Q&A的形式来写一下本书笔记前言,以此来这本书以及学习这本书的方方面面。
  • Q:这本书是关于什么的?
    A:这本书主要分为五大部分,围绕着CLR核心原理机制以及C#的编程编写展开。
  • Q:为什么要学习这本书?有什么好处?
    A:这本书是一个非常好的C#与CLR方面的“百科全书”,如果你在工作或者学习中需要大量运用到Unity或者是C#,那么概述是非常有必要至少看一次的,对于部分繁琐的概念可以适当略过,了解机制即可。当你学完之后再次编写C#代码你会有较为显著的能力提升,里面的代码书写方式以及规范值得每一个程序员去学习。
  • Q:什么样的人适合学习这本书?或者说处于什么样的学习阶段适合来看这本书?
    A:当你编写了一些C#的应用代码,或者是Unity中有了3-5个小游戏的完整开发体验之后,对于Class方方面面的概念以及设计模式有了全方面的了解,那么,是时候开始着手阅读这本书了!
    如果你是一个Unity或者C#方面的工程师,并且感觉自己代码书写不尽人意或陷入瓶颈那么也可以仔细地阅读该书。
  • Q:怎么去学习这本书?
    A:首先,这本书的内容顺序会和正常学习一门语言有所不不同,这本书更多的是思路以及机制的探讨并伴随大量示例代码,所以很容易在前面的章节出现后面知识点的内容,不过我在博客中对于这类知识点进行了相对应的补充,可以放心阅读。
    其次,如果你的期望并非是去微软当CLR架构师的话, 那么本书中的大部分概念性知识点只需要阅读第一句概括性文字即可,对于一些重要知识点(例如装箱拆箱的操作)等才需要仔细阅读,而对于大部分代码示例来说,如果演示的是CLR原理,那么完全可以不去阅读,如果演示的是C#编程操作,那么请务必仔细阅读。
    最后,这本书的描述习惯总是偏向于“总分总”或者是“分总”的形式(先写原因后写结果),这对于快速阅读以及新手阅读来说会造成一定的阅读困难,所以一定要耐心看完整段的描述,重点有时候会夹杂在文中。(大概有10%左右的知识点是这样)

该部分主要了解一下CLR模型即可

第一章 CLR的执行模型

  • CLR:Common Language Runtime,可由多重编程语言使用的“运行时(即Runtime)”。
    核心功能:内存管理,程序集加载,安全性,异常处理,线程同步。(P3 last)
image 46 - 《CLR via C#》笔记:第1部分 CLR基础
image 47 1024x643 - 《CLR via C#》笔记:第1部分 CLR基础
  • 除了生成IL,编译器要在每个托管模块中生成完整的元数据(metadata),一个数据表集合。元数据有多重用途:1、表面编译时对原生C/C++头和库文件的需求。2、VStudio用元数据帮助程序员写代码。3、CLR代码验证过程使用元数据确保代码只执行“类型安全”的操作 4、元数据允许将对象的字段序列化到内存块,发送给另一台机器然后反序列化。 5、允许垃圾回收期跟踪对象生存期。P5 last)
  • 程序集(assembly):首先,程序集是一个或多个模块/资源文件的逻辑性分组。其次,程序集是重用、安全性以及版本控制的最小单元。取决于你选择的编译器或工具,既可生成单文件程序集,也可生成多文件程序集。在CLR的世界中,程序集相当于“组件”。(P6 last3)
image 48 1024x598 - 《CLR via C#》笔记:第1部分 CLR基础
  • CLR的执行:(P11 last)
    1、下图中要执行main函数,CLR检测出main中代码引用所有类型,并分配一个内部数据结构管理引用类型访问
    2、Console类型定义的每个方法都有一个记录项,记录项都含有一个地址,根据此地址即可找到方法的实现。
    3、对这个结构初始化时,CLR将每个记录项都设置成包含在CLR内部的一个未编档函数,该函数称为JITCompiler。
  • main首次调用writeline,JITCompiler函数被调用,负责将IL代码编译成本机CPU指令。
    当第二次调用writeline会跳过函数直接执行内存块中代码。
image 54 1024x1024 - 《CLR via C#》笔记:第1部分 CLR基础
  • Visual Studio:“调试”(Debug)配置指定/optimize-和ldebug:full开关,而“发布”(Release)配置指定/optimize+和/debug:pdbonly开关(P13 4)
image 55 1024x187 - 《CLR via C#》笔记:第1部分 CLR基础
  • IL:1、基于栈 2、指令无类型(typeless)
    IL优势:对底层CPU抽象,具有应用程序的鲁棒性(健壮性)和安全性(P15 3)
  • 通过验证托管代码,可确保代码不会不正确地访问内存,不会干扰到另一个应用程序的代码。这样就可以放心地将多个托管应用程序放到同一个 Windows虚拟地址空间运行。用一个进程运行多个应用程序,可减少进程数,从而增强性能,减少所需的资源,健壮性也没有丝毫下降。这是托管代码相较于非托管代码的另一个优势。
image 56 1024x673 - 《CLR via C#》笔记:第1部分 CLR基础
  • Framework类库(Framwork Class Library,FCL):是一组程序集的统称,包含数千个类型定义。
    利用FCL创建应用程序举例:Web服务,基于HTML的Web窗体/MVC应用程序(网站),“富”Windows GUI应用程序,Windows控制台应用程序,Windows服务,数据库存储过程,组件库。(P20 1)
  • System命名空间(P21 3)
image 57 1024x481 - 《CLR via C#》笔记:第1部分 CLR基础
  • 通用类型系统(Common Type System,CTS):类型是CLR的根本,CTS为微软指定的规范类描述类型的定义和行为:(P22 1)
  • 字段(Field):作为对象状态一部分的数据变量。字段根据名称和类型来区分。
  • 方法(Method):针对对象执行操作的函数,通常会改变对象状态。方法有一个名称、一个签名以及一个或多个修饰符。签名指定参数数量(及其顺序);参数类型;方法是否有返回值;如果有返回值,还要指定返回值类型。
  • 属性(Property):对于调用者,属性看起来像是字段。但对于类型的实现者,属性看起来像是一个方法(或者两个方法R)。属性允许在访问值之前校验输入参数和对象状态,以及/或者仅在必要时才计算某个值。属性还允许类型的用户采用简化的语法。最后,属性允许创建只读或只写的“字段”。
  • 事件(Event):事件在对象以及其他相关对象之间实现了通知机制。例如,利用按钮提供的一个事件,可在按钮被单击之后通知其他对象。
  • CTS还指定了类型可见性规则以及类型成员的访问规则。(P23 2)
  • private:成员只能由同一个类(class)类型中的其他成员访问。
  • family:成员可由派生类型访问,不管那些类型是否在同一个程序集中。注意,许多语言(比如C++和C#)都用protected修饰符来标识family。
  • family and assembly:成员可由派生类型访问,但这些派生类型必须在同一个程序集中定义。许多语言(比如C#和Visual Basic)都没有提供这种访问控制。当然,IL汇编语言不在此列。
  • assembly:成员可由同一个程序集中的任何代码访问。许多语言都用internal修饰符来标识assembly。
  • family or assembly:成员可由任何程序集中的派生类型访问。成员也可由同一个程序集中的任何类型访问。C#用protected internal修饰符标识family or assembly。
  • public:成员可由任何程序集中的任何代码访问。
  • 公共语言规范(Common Langusge Specification,CLS):详细定义了一个最小功能机,以进行不同语言的集成。在跨语言编程时需要遵守CLS规范。
  • CLR支持三种托管代码与非托管代码的互相操作情形(以满足不重新设计现有代码的需求):1、托管代码能调用DLL中的非托管函数 2、托管代码可以使用现有的COM组件(服务器) 3、非托管代码可以使用托管类型(服务器)

该部分了解一下如何打包部署,公钥私钥的概念等即可

第二章 生成、打包、部署和管理应用程序及类型

  • .NET Framework正在尝试彻底解决DLL hell问题,解决应用程序状态在用户硬盘四处分散的问题。
    同时.NET Framework利用代码访问安全性(Code Access Security)让用户决定授予应用的信任权限。(P30 last)
  • 如何将包含多个类型的源代码文件转变为可以部署的文件:利用指令csc.exe Program.cs生成EXE文件(P31 1)
  • 元数据概述:探讨上述生成的Program.exe具体生成了什么。托管PE文件由4部分组成:PE32(+)头、CLR头、元数据以及IL。(P33 last2)Progam是公共密封类,从System.Object派生,还定义了两个方法:Main和.ctor(构造器),Main是公共静态方法,用IL代码实现,构造器是公共方法,也用IL实现。(P37 last)
    元数据是由几个表构成的二进制块:定义表(definition table)、引用表(reference table)、清单表(mainifest table)。ILDasm会处理元数据表。(P34 last)
image 29 - 《CLR via C#》笔记:第1部分 CLR基础
image 30 - 《CLR via C#》笔记:第1部分 CLR基础
image 31 - 《CLR via C#》笔记:第1部分 CLR基础
  • 将模块合并成程序集:Program.exe是程序集不是含有元数据的PE文件。程序集是一个或多个类型定义文件及资源文件的集合。
    CLR操作程序集,会首先加载包含“清单”元数据表的文件,在根据“清单”来获取程序集中的其他文件名称。程序集特点:1、定义了可重用的类型 2、用一个版本号标记 3、可以关联安全信息。(P39 1)
image 32 - 《CLR via C#》笔记:第1部分 CLR基础
  • 使用VStudio将程序集添加到项目中(P44 last),使用程序集连接器(P45 3),为程序集添加资源文件(P46 last2)程序集版本信息(P47 last)
  • 版本号:下图所示为2.5.719.2。2.5即公众看到的版本号,719是程序集的build号,2指出当前build的修订次数。如果公司每天都生成程序集,那么应每天递增build号。
    程序集三个版本号:AssemblyFileVersion、AssemblyInformationVersion、AssemblyVersion(P50 3
image 33 - 《CLR via C#》笔记:第1部分 CLR基础
  • 语言文化(P51 2)
  • 简单应用程序部署(私有部署的程序集)(P52 2),简单管理控制(P53 last3)

该部分看看图即可

第三章 共享程序集和强命名程序集

  • 本章节重点:如何创建可由多个应用程序共享的程序集。
  • CLR支持两种程序集:弱命名程序集(weakly named assembly)和强命名程序集(strongly named assembly)。两者程序集结构完全相同,生成工具也相同。
    区别:强命名程序集使用发布者的公钥/私钥进行了签名。(P58 4)弱命名只能以私有方式部署,强命名可以私有也可以全局。
  • 为程序集分配强名称(P59 2),公钥长度太大,为了简化工作,设计使用了公钥标记(public key token),该标记为公钥的64位哈希值。文件签名的准确含义:生成强命名程序集时,程序集的FileDef清单元数据表列出构成程序集的所有文件。每将一个文件名添加到清单,都对文件内容进行哈希处理。(P61 2)
image 34 - 《CLR via C#》笔记:第1部分 CLR基础
  • 全局程序集缓存(Global Assembly Cache,GAC):由多个应用程序访问的程序集必须放到公认的目录,该目录位置即全局程序集缓存。(P63 3)
  • 在生成的程序集中引用强命名程序集(P65 3)
  • 强命名程序集能防篡改(P66 3)
  • 延迟签名(P67 1)
  • 私有部署强命名程序集(P69 1)
  • “运行时”如何解析类型引用:1、相同文件-早期绑定 2、不同文件,相同程序集-当前程序集元数据的FileDef表 3、不同文件、不同程序集-加载被引用程序集的清单文件(P70 1)
image 35 - 《CLR via C#》笔记:第1部分 CLR基础
  • 高级管理控制:演示如何将被引用程序集的文件移动到应用程序基目录下的一个子目录,以及CLR如何通过应用程序的XML配置文件来定位发生移动的文件。(P73 last)发布者策略控制(P75 last2)

LEAVE A COMMENT