CLR:是一个可由多种编程语言使用的“运行时”。
CLR的核心功能(比如 内存管理、程序集加载、安全性、异常处理、线程同步)可由面向CLR的所有语言使用。
CLR是完全围绕类型展开的。
面向CLR的语言编译器:
Microsoft:C++/CLI、C#、Visual Basic、F#、Iron Python 以及IL汇编器。
其他公司、学院:Ada、PAL、Caml、COBOL、LOGO、PHP...
托管模块的组成部分:PE32/PE32+头、CLR头、元数据、IL代码。
IL基于栈的。
IL指令时“无类型”(typeless)的
IL提供的优势:应用程序的健壮性和安全性,对底层CPU的抽象。
将IL编译成本地CPU指令时,CLR会执行一个名为验证的过程。(检查高级IL代码,确定代码所做的一切都是安全的。)
在托管模块的元素中,包含了要由验证过程使用的所有方法和类型信息。
在Windows中,每个进程都有它自己的虚拟地址空间。(保证程序的健壮性,稳定性;一个进程无法干扰另一个进程)
托管代码相较于非托管代码的优势:在一个操作系统进程中运行多个应用程序,可减少进程数,从而增强性能(windows进程需要使用大量操作系统资源)。
不安全代码 使用场景:直接操作内存地址的代码称为不安全代码,并可操作这些地址处的字节。通常只有在与非托管代码进行互操作,或者在提升对效率要求极高的一个算法的性能的时候,才需要这样做。
不安全代码 风险:可能破坏数据结构,危害安全行性,甚至可能造成新的安全漏洞。
C#编译器要求包含不安全代码的所有发明合法都用unsafe关键字标记,要求使用/unsafe编译器开关来编译源码。
本地代码生成器:NGen.exe
1.作用:
加快应用程序的启动速度。
减小应用程序的工作集。
2.NGen生成的文件存在的问题:
没有知识产权保护。
NGen生产的文件可能失去同步。
较差的执行时性能。
正是因为存在上述这些问题,所以在考虑shiyNGen.exe时,务必非常谨慎。对于服务器端的应用程序,NGen.exe的作用并不明显,甚至毫无用处,这是因为只有第一个客户端请求才会感受到性能的下降,后续的所有客户端请求都能以全速运行。此外,对于大多数服务器应用程序,由于只需要代码的一个实例,所以无法从工作集的缩小中获得任何好处。还需要注意,NGen.exe2.0之前生成的映像不能在不提部分的AppDomain之间共享。因此,如果一个程序集要在跨AppDomain的环境中使用(比如ASP.NET),用NGen来生成它是没有任何好处的。(不过,这一限制在NGen2.0之后已经不存在了。)
对于客户端的应用程序,也许能用NGen.exe加快启动速度,或者缩小工具集(如果程序集同时由多个应用程序使用)。即使一个程序集不是由多个应用程序使用,用NGen来生成它,也有助于增强工作集。此外,假如用NGen.exe来生成一个客户端应用程序的所有程序集,CLR根本不需要加在JIT编译器,从而进一步缩小工作集,当然,只要有一个程序集不是用NGen生成的,或者程序集的一个由NGen声生成的文件无法使用,那么还是会加载JIT编译器,应用程序的工作集将随之增大。
Framework类库
.NET Framework 中包含了Framework类库(Framework Class Library)。FCL是一组DLL程序集的统称,其中含有数千个类型定义,每个类型都公开了一些功能。
下面列举了应用程序开发人员可以利用这些程序集创建的一部分应用程序:
Web Service
Web Form
Windows应用程序
RIA
Windows控制台应用程序
Windows服务
数据库存储过程
组件库
所有的应用程序都要使用来自System命名空间的类型。
命名空间 | 内容说明 |
System | 包含每个应用程序都要用到的所有基本类型 |
System.Data | 包含用于和数据库通信以及处理数据的类型 |
System.IO | 包含用语执行流I/O以及浏览目录/文件的类型 |
System.Net | 包含进行低级网络通信,并与一些常用Internet协议协作的类型 |
System.Runtime.InteropService | 包含允许托管代码访问非托管操作系统平台功能(比如COM组件以及Win32或定制DLL中的函数)的类型 |
System.Security | 包含用语保护数据和资源的类型 |
System.Text | 包含处理各种编码方式(比如ASCII和Unicode)的文本的类型 |
System.Threading | 包含用于异步操作和同步资源访问的类型 |
System.Xml | 包含用于处理XML架构(XML Schema)和数据的类型 |
通用类型系统CTS
CLR是完全围绕类型展开的。CTS描述了类型的定义和行为。
CTS规则:
1.CTS规范规定一个类型可以包含零个或者多个成员。(成员包括:字段、方法、属性、事件)
2.CTS指定了类型可视性规则以及类型成员的访问规则。(private、protected、internal、public...)
3.CTS为类型继承、虚方法、对象生存期等定义了相应规则。
4.所有的类型最终必须从预订一的System.Object类型继承。
System.Object类型允许做的事情:
1)比较两个实例的相等性。
2)获取实例的哈希码。
3)查询一个实例的真正类型。
4)执行实例的浅(按位)拷贝。
5)获取实例对象的当前状态的一个字符串表示。
公共语言规范CLS
COM允许使用不同的语言创建对象的相互通信。CLR可以集成所有语言,允许在一中语言中使用另一种语言创建的对象。之所以能实现这样的集成,是因为CLR使用了标准类型集、元数据(自描述的类型信息)以及公共执行环境。
CLS:CLS详细定义了一个最小功能集。任何编译器生成的类型要想兼容雨由其他“符合CLS、面向CLR的语言”所生成的组件,就必须支持CLS定义的这个最小功能集。
每种语言都提供了CLR/CTS的一个子集以及CLS的一个超集(但不一定是同一个超集)。
一种语言定义一个类型时,如果希望在另一种语言中使用该类型,就不要在该类型的public和protected成员中使用位于CLS外部的任何功能。否则,其他开发人员使用其他语言写代码时,就可能无法访问这个类型的成员。
托管代码与非托管代码的互操作性
CLR支持三种互操作的情形:
1.托管代码能够调用DLL中的非托管代码
2.托管代码可以使用现有的COM组件(服务器)
3.非托管代码可以使用托管类型(服务器)