CLR via C#学习笔记
第1章 CLR的执行模型
托管模块的各个组成部分:PE32或PE32+头,CLR头,元数据,IL(中间语言)代码。
高级语言通常只公开了CLR的所有功能的一个子集。然而,IL汇编语言允许开发人员访问CLR的所有功能。
JITCompiler函数负责将一个方法的IL代码编译成本地CPU指令。由于IL是“即时”(just in time)编译的,所以通常将CLR的这个组件称为JITter或者JIT编译器。
Microsoft定义了一个“公共语言规范”(Common Language Specification, CLS),它定义了所有语言都必须支持的一个最小功能集。
第2章 生成、打包、部署和管理应用程序及类型
响应文件(response file)是一个文本文件,其中包含一组编译器命令行开关。
除了在命令行上显式指定的文件,编译器还会自动查找两个名为CSC.rsp的文件(本地的和全局的) 。
本地和全局响应文件中的某个设置发生冲突,将以本地文件的设置为准。类似地,命令行上显式指定的设置将覆盖本地响应文件中的设置。
为了增加趣味性,在ILDasm中选择“视图”|“统计”,会显示有趣的信息。
AssemblyVersion 这个版本号非常重要,它唯一性地标识了一个程序集。一个程序集将与所引用的程序集的一个特定的版本紧密绑定到一起。
第3章 共享程序集和强命名程序集
显然,只根据文件名来区分程序集是不够的。CLR必须提供对程序集进行唯一性标识的机制。这正是“强命名程序集”的来历。一个强命名的程序集具有4个重要attributes,它们共同对程序集进行了唯一性标识:一个文件名(不计扩展名)、一个版本号、一个语言文化(culture)标识以及一个公钥。
由于公钥是非常大的数字,所以经常使用从公钥派生的一个小的哈希值。这个哈希值称为公钥标记(public key token)。
CLR在做出安全或信任决策时,永远都不会使用公钥标记,因为几个公钥可能在哈希处理之后得到同一个公钥标记。
如果一个程序集要由多个应用程序访问,必须把它放到一个已知的目录中,而且CLR在检测到对该程序集的一个引用时,必须知道自动检查该目录。这个已知的位置称为全局程序集缓存(Global Assembly Cache, GAC).
将一个强命名的程序集安装到GAC时,系统会执行一次检查,核实含有清单的那个文件没有被篡改。这个检查只在安装时执行一次。相反,从非GAC的一个目录加载强命名程序集时,CLR会校验程序集的清单文件,核实文件的内容未被篡改,造成该文件每次加载都会带来额外的性能开销。
第4章 类型基础
is操作符、as操作符永远不会抛出异常。
is操作符使用如下时:
if (o is Employee)
{
Employee e = (Employee) o;
}
CLR实际会检查两次对象的类型,无疑对性能造成一定影响。C#专门提供了as操作符,目的就是简化这种代码的写法,同时提升其性能。
Employee e = o as Employee;
if (e != null) { }
如果o不兼容于Employee类型,as操作符会返回null,这只造成CLR校验一次对象的类型。if语句只是检查e是否为null,这个检查的速度比校验对象的类型快得多。
C#编译器提供了一个名为外部别名(extern alias)的功能,它解决了这个虽然罕见但仍有可能发生的问题:通过编程来区分不同的程序集,而非仅能区分不同的命名空间。外部别名还允许从同一个程序集的两个(或更多)不同的版本中访问一个类型。欲知外部别名的详情,请参见C#语言规范。
除了全局性地打开或关闭溢出检查,程序员还可在代码的特定区域控制溢出检查。C#通过提供checked和unchecked操作符来实现这种灵活性。
第5章 基元类型、引用类型和值类型
如果你定义的一个类型重写了Equals方法,那么还应重写GetHashCode方法,确保相等性算法和对象哈希码算法是一致的。这是因为在System.Collections.Hashtable类型、System.Collections.Generic.Dictionary类型以及其他一些集合的实现中,要求两个对象为了相等,必须具有相同的哈希码。
不要混淆dynamic和var。用var声明一个局部变量只是一种简化语法,它要求编译器根据一个表达式推断具体的数据类型。var关键字只能用于声明方法内部的局部变量,而dynamic关键字可用于局部变量、字段和参数。表达式不能转型为var,但能转型为dynamic。必须显式初始化用var声明的变量,但无需初始化用dynamic声明的变量。
代码使用dynamic表达式/变量来调用一个成员时,编译器会生成特殊的IL代码来描述所需的操作。这种特殊的代码称为payload(有效载荷)。
虽然能用动态功能简化语法,但也要看是否值得。毕竟,加载所有这些程序集以及额外的内存消耗,会对性能产生额外的影响。
第6章 类型和成员基础
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/67795.html