从
.NET CLI
(第
3
版)看
.NET Framework 2.0
(
V0.01
)
2005
年
6
月,
.NET CLI
(第
3
版)正式成为
ECMA
标准
ECMA-335
(第
3
版),第
3
版
.NET CLI
对应
.NET Framework 2.0
。了解第
3
版
.NET CLI
对了解
.NET Framework 2.0
内核有重要意义,本文试通过简要分析
.NET CLI
(第
3
版)包含的内容,初步了解一般资料中较少涉及的
.NET Framework 2.0
内核相关信息。
1
什么是
.NET CLI
.NET CLI
是
.NET
公共语言基础结构(
.NET Common Language Infrastructure
)的缩写,
.NET Framework
基于
.NET CLI
。
.NET CLI
文档中对
.NET CLI
的定义是:
.NET CLI
定义了一个公共语言基础结构,在公共语言基础结构中,各种不同的高级语言开发的应用程序,无需修改程序以适应不同的系统环境特有的特性,就可以在不同的系统环境下运行。
这个定义点明了
.NET Framework
的基本特性:
1
、
.NET Framework
和
Java
一样,具有跨平台性,“不同的系统环境”实际上就是不同的硬件和软件平台(包括操作系统),理论上说,在任何硬件和软件平台上,只要实现
.NET Framework
,就可以不加修改地运行任何
.NET
应用程序,而无需考虑平台自身的特性。
2
、
.NET Framework
还可以支持多种高级语言(跨语言性),任何
.NET
编程语言,即
.NET
平台支持的高级语言,开发的应用程序在
.NET Framework
上是等价的,都可以在
.NET Framework
上运行。
无论商业的炒作如何进行,系统底层程序员应该保持清醒的头脑,从
.NET Framework
的基本特性看来,通常被称为
.NET CLR
(
.NET
公共语言运行时,
.NET Common Language Runtime
)的
.NET Framework
底层,本质上一定是类似于
Java
虚拟机(
Java VM
)的虚拟机,
.NET CLR
执行的代码一定也是一种虚拟机代码或者中间代码,否则
.NET Framework
不可能实现跨平台,特别是适应不同的硬件平台。因为不同的硬件平台,
CPU
的指令集可能是不同的,只有通过虚拟机将中间代码在运行时动态转换为
CPU
指令集支持的本机代码,才能实现中间代码在不同硬件平台上的同样执行,进而实现适应不同的硬件平台。
.NET Framework
可以支持多种
.NET
编程语言,这意味着:任何
.NET
编程语言的源程序最终都编译成相同的中间代码,也就是可以在
.NET CLR
(虚拟机)上运行的虚拟机代码。
2 .NET CLI
包含的内容
.NET CLI
(第
3
版)文档包含下列部分:
1
、概念和体系结构:描述
.NET CLI
的全部体系结构,提供公共类型系统(
CTS
,
Common Type System
)、虚拟执行系统(
VES
,
Virtual Execution System
)和公共语言规范(
CLS
,
Common Language Specification
)的标准化描述,还提供对元数据(
Metadata
)的信息性描述。
2
、元数据的定义和语义:提供元数据的标准化描述,包括元数据在
.NET
扩展
PE
文件格式中的位置(以
.NET
扩展
PE
文件格式的形式表示),元数据的逻辑内容(以表格及其关联的集合的形式表示,实际上使用了形式化方法表示)和元数据的语义(以汇编成为虚拟机代码的汇编器
ilasm
理解的形式表示)。
3
、
CIL
指令集:描述公共中间语言(
CIL
,
Common Intermediate Language
)指令集。
CIL
又称
MSIL
(微软中间语言,
Microsoft Intermediate Language
),
CIL
指令就是虚拟机代码或者中间代码的指令。
4
、
Profile
和库:提供
CLI
库的简要介绍,以及将其分解为
Profile
和库的规范。这里有一个配套的文件
CLILibraryTypes.xml
,考虑过随这一部分一起发布,不过该文件是
XML
格式的,该文件提供了
CLI
库中每一个类、值类型和接口的细节说明。“
Profile
”一词在这里的含义是库的集合,一起组合起来构成提供一定功能级别的一致性整体,换而言之,不同的
Profile
对应不同的库集合,提供的功能级别也不同,“
Profile
”一词亦可翻译成“库概要”或者“库配置”,但切勿翻译成“配置文件”。
5
、调试交换格式:可交换(
.NET CLI
通用)调试信息的格式。
6
、附件
从
.NET CLI
文档包含的整体内容来看,
.NET CLI
包含下列内容:
1
、
CLS
(
.NET CLS
)
2
、
CTS
(
.NET CTS
)
3
、
VES
VES
是通常所说的
.NET CLR
的核心,这也是
.NET CLR
本质上是虚拟机的又一证明。
4
、元数据
包括
.NET
扩展
PE
文件格式。
5
、
CIL
(
MSIL
)
6
、库和
Profile
7
、调试信息的格式
8
、附件
实现
.NET CLI
定义的公共语言基础结构即可实现
.NET Framework
的子集。了解
.NET CLI
可以从底层较为详细地了解
.NET CLS
、
.NET CTS
、
VES
、
Metadata
、
NET
扩展
PE
文件格式、
CIL
等,这是系统底层程序员了解
.NET Framework
内核以及开发相关软件所必需的。推荐任何一位
.NET
系统底层程序员认真阅读
.NET CLI
文档,
.NET CLI
文档可在
Microsoft
公司网站上下载。
3
对
.NET CLI
包含内容意义的分析
.NET CLI
提供了一个可执行代码(
CIL
代码)和代码运行的执行环境(
VES
)的规范,提供给
VES
可执行代码的是模块(
Module
),模块是一个文件格式中包含可执行内容的文件。
.NET CLI
的核心是一个统一的类型系统(
CTS
),所有的
.NET
编程语言编译器、工具甚至
.NET CLI
自身都使用
CTS
,
CTS
模型定义了一组
.NET CLI
在定义、使用和管理类型时遵循的规则,
CTS
确定了实现跨语言集成、类型安全和高性能代码执行的框架,通过描述
CTS
可以描述
.NET CLI
的体系结构。
元数据用于描述和引用
CTS
定义的类型。因为元数据包含在
.NET
编程语言编译生成的最终的可执行文件——
.NET
扩展
PE
文件中,所以所有的
.NET
可执行文件中,仍然包含源程序中的所有类型的定义(描述),通常所说的
.NET
编程语言中的类(
Class
),也是
CTS
中定义的一种类型——引用类型的一种,这意味着所有类型,包括类,可以在
.NET
可执行文件运行时动态访问,例如在运行时动态确定使用某种类创建对象,而不是在编译时就确定创建对象的类。
CLS
是
.NET
编程语言设计者和框架(例如类库)设计者之间的协定,
CLS
指定了
CTS
的子集和用法约定,编程语言通过实现
CLS
定义的
CTS
的最小化部分即可获得最大的访问框架的能力。例如:
类库暴露出的接口如果只使用
CLS
指定的
CTS
子集中的类型,并遵循
CLS
协定,那么类库就可以被任何
.NET
编程语言调用
。制定
CLS
的目的是考虑到跨语言集成,因为各种
.NET
编程语言虽然有其共性,但也有其特性,例如
C#
支持运算符重载而
VB.NET
不支持,同样
VB.NET
支持后期绑定语法而
C#
不支持,跨语言调用的类型必须是各种
.NET
编程语言都能支持的类型,所以要定义各种
.NET
编程语言都支持的
CTS
子集和用法约定。任何
.NET
编程语言都必须遵循
.NET CLS
,例如
VB6
对面向对象的支持不完整,但作为
.NET
编程语言的
VB.NET
,必需完全支持面向对象,这导致了
VB6
和
VB.NET
的不兼容。
VES
实现并强制遵守
CTS
。
.NET
可执行文件完全由类型(包括类)构成,
VES
执行
.NET
可执行文件,实际上是执行类型,本质上是在元数据——类型定义的驱动下执行类型中方法的实现,方法的实现可以是
CIL
代码,也可以是本机代码,例如
Visual C++.NET
中的混合程序集同时包含
CIL
代码和本机代码,这就是托管执行(受控执行,
Managed Execution
)的本质。
VES
通过执行类型来实现并强制遵守
CTS
,因为类型是遵循
CTS
的,
VES
只能执行遵循
CTS
的类型。
虚拟机代码——
CIL
代码的指令集,近似一种虚拟的
RISC
体系结构
CPU
的指令集,
CIL
指令同样可以用一种虚拟的汇编语言表示,称为
IL
汇编语言。
.NET
可执行文件中的类型,其方法只要是用
CIL
代码实现的,可以反汇编成
IL
汇编语言的形式。因为
CIL
代码本质上是一种虚拟机代码,要将
CIL
代码反编译成
.NET
编程语言的源程序形式也是很简单的,如同
Java
可执行文件可以反编译成
Java
源程序一样。
4
第
3
版
.NET CLI
中添加的内容
第
2
版
.NET CLI
于
2002
年发布,对应
.NET Framework 1.0
,第
3
版
.NET CLI
对应
.NET Framework 2.0
。对比第
2
版
.NET CLI
和第
3
版
.NET CLI
,可以发现第
3
版
.NET CLI
添加的内容,最重要的就是对泛型(参数化的类型,
Generics
)的支持,这与
.NET Framework 2.0
的底层——
.NET CLR 2.0
添加的最重要内容是一致的。
5 .NET CLR
与
Java VM
的异同
.NET CLR
的本质和
Java VM
类似,都是虚拟机,这与
Microsoft
声称
.NET Framework
可以跨平台是对应的。
但是
.NET CLR
并不强调
100
%的平台无关性,托管执行的本质只是元数据驱动执行,尽管类型中方法的实现一般都使用
CIL
代码,例如
C#
和
VB.NET
的编译器只生成
CIL
代码,但不排除使用本机代码,例如
Visual C++.NET
的编译器可以生成同时包含
CIL
代码和本机代码的可执行文件,本机代码显然是平台相关的。
.NET Framework
中,很多
.NET
框架类库的实现只是一种对
Windows
平台的包装,最终调用的还是
Windows API
或者
Windows
相关服务,例如企业服务(
Enterprise Services
)最终调用
COM+
企业组件服务。
.NET
框架类库是
.NET
应用程序调用的
API
,显然,使用了上述
.NET
框架类库的
.NET
应用程序是不可能离开
Windows
平台的。
.NET
应用程序还可以直接调用
Windows API
,直接调用
Windows API
的
.NET
应用程序更不可能离开
Windows
平台。
可见
Microsoft
并不把跨平台作为
.NET Framework
追求的首要目标,
.NET CLR
是和
Windows
平台甚至硬件平台协同工作的,而
Java VM
的目标则是实现完全的跨平台,在各种硬件和软件平台上都有
Java API
的独立实现,可见二者的设计首要目标并不相同。
所以
.NET CLR
称为“
Runtime
(运行时)”,而
Java VM
称为“
Virtual Machine
(虚拟机)”还是很贴切的。
Microsoft
会让
.NET Framework
完全跨平台吗?笔者看来现在不会,否则如何保持
Windows
平台的垄断地位?
.NET CLI
定义的只是
.NET Framework
的子集,仅此而已。
6 .NET Framework 3.0
Windows Vista
(
Windows NT 6.0
)将于
2006
年年底到
2007
年年初的时间正式发布,
Windows Vista
中包含了
.NET Framework 3.0
。
.NET Framework 3.0
是
WinFX
正式发布时的称呼,
.NET Framework 3.0
提供了
4
个全新的子系统,对于程序员来说可以认为是
4
组全新的
API
,还包括全新的程序设计体系结构,它们分别是:图形用户界面子系统
WPF
(
Windows
表示层基础,
Windows Presentation Foundation
)、安全体系
CardSpace
、网络服务通信子系统
WCF
(
Windows
通信基础,
Windows Communication Foundation
)和工作流子系统
WF
(
Windows
工作流基础,
Windows Workflow Foundation
)。
实际上
.NET Framework 3.0
的核心仍然是
.NET Framework 2.0
,其底层仍然是
.NET CLR 2.0
,因此
.NET Framework 3.0
的发布对系统底层程序员的冲击相对比较小。从
.NET Framework 3.0
的核心仍然是
.NET Framework 2.0
看来,
Microsoft
无法放弃
Windows API
时代的大量资源,包括
COM
/
COM+
、
DirectX
等,
.NET Framework
在一段时期内仍然不会完全取代
Windows API
,系统底层程序员仍然大有可为。
引用本文开始处的一句话:无论商业的炒作如何进行,系统底层程序员应该保持清醒的头脑。