Microsoft 中间语言(Microsoft Intermediate Language, MSIL 或简称为 IL), .NET 上所有编译好的代码都要使用这种语言。
通用类型系统 (Common Type System, CTS)
公共语言规范 (Common Language Specification, CLS)
C#是一种相当新的编程语言, C#的重要性体现在以下两个方面:
● 它是专门为与 Microsoft 的.NET Framework 一起使用而设计的。 (.NET Framework 是一个功能非常丰富的平台,可开发、部署和执行分布式应用程序)。
● 它是一种基于现代面向对象设计方法的语言,在设计它时, Microsoft 还吸取了其他类似语言的经验,这些语言是近 20 年来面向对象规则得到广泛应用后才开发出来的。
有一个很重要的问题要弄明白: C#就其本身而言只是一种语言,尽管它是用于生成面向.NET 环境的代码,但它本身不是.NET 的一部分。 .NET 支持的一些特性, C#并不支持。而 C#语言支持的另一些特性, .NET 却不支持(例如运算符重载)!
NET Framework 的核心是其运行库的执行环境,称为公共语言运行库(CLR)或.NET 运行库。通常将在 CLR 的控制下运行的代码称为托管代码(managed code)。但是,在 CLR 执行编写好的源代码之前,需要编译它们(在 C#中或其他语言中)。在.NET 中,编
译分为两个阶段:
(1) 把源代码编译为 Microsoft 中间语言(IL)。
(2) CLR 把 IL 编译为平台专用的代码。这个两阶段的编译过程非常重要,因为 Microsoft 中间语言(托管代码)是提供.NET 的许多优点的关键。
Microsoft 中间语言与 Java 字节代码共享一种理念:它们都是低级语言,语法很简单(使用数字代码,而不是文本代码),可以非常快速地转换为内部机器码。对于代码来说,这种精心设计的通用语法有很重要的优点:平台无关性、提高性能和语言的互操作性
JIT 编译器并不是把整个应用程序一次编译完(这样会有很长的启动时间),而是只编译它调用的那部分代码(这是其名称由来)。代码编译过一次后,得到的内部可执行代码就存储起来,直到退出该应用程序为止,编译过程的最后一部分是在运行时进行的, JIT 编译器确切地知道程序运行在什么类型的处理器上,可以利用该处理器提供的任何特性或特定的机器代码指令来优化最后的可执行代码。
传统的编译器会优化代码,但它们的优化过程是独立于代码所运行的特定处理器的。这是因为传统的编译器是在发布软件之前编译为内部机器可执行的代码。即编译器不知道代码所运行的处理器类型,例如该处理器是 x86 兼容处理器还是 Alpha 处理器,这超出了基本操作的范围。例如 Visual Studio6 为一般的奔腾机器进行了优化,所以它生成的代码就不能利用奔腾 III 处理器的硬件特性。相反,JIT 编译器不仅可以进行 Visual Studio 6 所能完成的优化工作,还可以优化代码所运行的特定处理器。
Visual C++ 6 有许多 Microsoft 对 Windows 的特定扩展。通过 Visual C++ .NET,又加入了更多的扩展内容,来支持.NET Framework。现有的 C++源代码会继续编译为内部可执行代码,不会有修改,但它会独立于.NET 运行库运行。如果让 C++代码在.NET Framework 中运行,就可以在代码的开头添加下述命令:
#using <mscorlib.dll>
还可以把标记/clr 传递给编译器,这样编译器假定要编译托管代码,因此会生成中间语言,而不是内部机器码。 C++的一个有趣的问题是在编译托管代码时,编译器可以生成包含内嵌本机可执行代码的 IL。这表示在 C++代码中可以把托管类型和非托管类型合并起来,因此托管 C++代码:
class MyClass
{
定义了一个普通的 C++类,而代码:
_ref class MyClass
{
生成了一个托管类,就好像使用 C#或 Visual Basic 2008 编写类一样。实际上,托管 C++比 C#更优越的一点是可以在托管 C++代码中调用非托管 C++类,而不必采用 COM 交互功能。
下面就是中间语言的主要特征:
● 面向对象和使用接口
● 值类型和引用类型之间的巨大差别
● 强数据类型
● 使用异常来处理错误
● 使用特性(attribute)