公共语言运行时(CLR):
.NET CLR提供一个公共上下文,执行所有.NET组件,不考虑具体编写语言。
为实现语言互操作性,编译器生成的代码必须遵守严格的CLR类型系统,即为CLR兼容类型。
托管代码:
.NET CLR管理代码行为的方方面面,针对CLR的代码,称为托管代码,统一由CLR管理。
编译.NET托管代码:
1.高级语言(C#) -----------编译-----------> IL(中间语言,非原始机器码,封装在DLL,EXE中)
说明:IL保存到DLL,EXE后,编译器为每个类方法创建一机器代码存根。该存根调用JIT,将自身方法地址作为参数传入。
2.IL---------- 将在运行时JIT(即时编译)--------------> CPU执行原始机器码
说明:初次运行该方法时,首先调用方法存根,存根调用JIT,JIT将该方法的IL编译为原始机器码,本地保存。然后.NET再次调用该方法,从而真正执行程序。
因此,每个被调用方法只JIT一次,从未调用的方法永不编译。当程序终止,本地保存的代码被删除。
中间语言(IL):
IL是所有.NET程序语言的共同点,是实现语言互操作的基础。CLR仅仅只知道IL。
global命名空间:
默认,所有C#命名空间内嵌在global根命名空间中。global::显示告诉编译器从global下开始解析。
程序集宿主:
只要工作在一个调试会话中,生成应用程序集,除应用程序集.exe外,还生成应用程序名.vshost.exe程序集。
为了调试,加载.exe到应用程序名.vshost.exe中,进行调试。vshost.exe用于承载应用程序进程。
程序集(Assembly):
EXE应用程序集,DLL库程序集
命名空间和程序集没有联系:一个程序集可以定义多个命名空间,多个程序集可为一个命名空间。
程序集元数据(Metadata):
描述程序集中类型。包括程序集可用类型,命名空间,类型名称,可见性,基类,接口,方法,方法参数等信息。
编译器将元数据嵌入DLL,EXE文件中的每个模块。CLR兼容编译器都要求生成元数据。
.NET反射机制,智能感知,转到定义等功能,通过读取元数据,实现。
程序集清单(Manifest):
描述程序集自己,提供程序集所有模块,组件共享逻辑属性。包括程序集名,版本号,地区设置,可选强名,效验程序集安全要求,组成程序集所有文件名,哈希函数。
.NET中,每个清单包含程序集不同模块的哈希密码。加载时,重新计算该模块的哈希密码。如与清单中不同,拒绝加载,抛出异常。避免模块被恶意换掉。
不同于元数据,无需为程序集每个模块嵌入清单,仅有一个主模块嵌入清单。
通过使用特定程序集属性,可为编译器提供信息:AssemblyInfo.cs
构成程序集:
1.每个程序集必须只包含一个清单。
2.程序集中每个模块必须包含各自的元数据。