.NET结合Java和COM解决方案两者优点来解决互操作性问题。类似于COM定义的标准二进制格式,.NET定义了一个称为通用类型系统Common Type System(CTS)的类型标准。这个类型系统不但实现了COM的变量兼容类型,而且还定义了通过用户自定义类型的方式来进行类型扩展。任何以.NET平台作为目标的语言必须建立它的数据类型与CTS的类型间的映射。所有.NET语言共享这一类型系统,实现它们之间无缝的互操作。该方案还提供了语言之间的继承性。例如,用户能够在VB.NET中派生一个由C#编写的类。
很显然,编程语言的区别不仅仅在于类型。例如,一些语言支持多继承性,一些语言支持无符号数据类型,一些语言支持运算符重载。用户应认识到这一点,因此.NET通过定义公共语言规范(CLS:Common Language Specification),限制了由这些不同引发的互操作性问题。CLS制定了一种以.NET平台为目标的语言所必须支持的最小特征,以及该语言与其他.NET语言之间实现互操作性所需要的完备特征。认识到这点很重要,这里讨论的特征问题已不仅仅是语言间的简单语法区别。例如,CLS并不去关心一种语言用什么关键字实现继承,只是关心该语言如何支持继承。
CLS是CTS的一个子集。这就意味着一种语言特征可能符合CTS标准,但又超出CLS的范畴。例如:C#支持无符号数字类型,该特征能通过CTS的测试,但CLS却仅仅识别符号数字类型。因此,如果用户在一个组件中使用C#的无符号类型,就可能不能与不使用无符号类型的语言(如VB.NET)设计的.NET组件实现互操作。这里用的是“可能不”,而不是“不可能”,因为这一问题实际依赖于对non-CLS-compliant项的可见性。事实上,CLS规则只适用于或部分适用于那些与其他组件存在联系的组件中的类型。实际上,用户能够安全实现含私有组件的项目,而该组件使用了用户所选择使用的.NET语言的全部功能,且无需遵守CLS的规范。另一方面,如果用户需要.NET语言的互操作性,那么用户的组件中的公共项必须完全符合CLS规范。让我们来看下面的C#代码:
public class Foo
{
// The uint(unsigned integer)type is non-CLS compliant.
//But since this item is private,the CLS rules do not apply.
private uint A = 4;
// Since shis uint member is public,we have a CLS
// compliance issue.
public uint B = 5;
// The long type is CLS compliant.
public long GetA()
{
return A;
}
}
最后一个C是公共语言运行库Common Language Runtime(CLR)。简单地说,CLR是CTS的实现,也就是说,CLR是应用程序的执行引擎和功能齐全的类库,该类库严格按照CTS规范实现。作为程序执行引擎,CLR负责安全地载入和运行用户程序代码,包括对不用对象的垃圾回收和安全检查。在CLR监控之下运行的代码,称为托管代码(managed code)。作为类库,CLR提供上百个可用的有用类型,而这些类型可通过继承进行扩展。对于文件I/O、创建对话框、启动线程等类型——基本上能使用Windows API来完成的操作,都可由其完成。
让我们正确看待“3C”。开发人员在构建自己的分布式应用程序时,因为用户在编程时将直接面对CLR,应将主要精力放在学习了解CLR上,而不是CTS和CLS。而对于希望以.NET平台为目标的语言和工具开发商来说,就需要深入理解CTS和CLS。互操作性组件是分布式应用的关键,因此理解.NET如何通过定义公共类型实现这一目标,也就显得十分重要。
所有.NET语言编译器生成与平台无关的代码,称为通用中间语言(CIL,简称IL)。从概念上来讲,这一点非常类似Java中的字节码。但与Java字节码所不同的是,Microsoft设计的IL可以由任一语言编译器很容易地生成。
前面提到的,程序集包含IL,而不是源代码。在运行过程中,当第一次调用一个方法,为了更快的执行程序,实时Just-In-Time (JIT)编译器将该方法的IL代码转换成源代码(与平台有关)。.NET只编译需要在运行库中使用的那部分IL。当然,它将会把转换得到的源代码放入缓存中,以便以后的调用能够直接使用该源代码。
同时考虑到CTS和CLR,IL为.NET提供了除了Windows之外,还能移植到其他操作系统的可能。如果可能的话,用户可以用任何一种语言开发与平台无关的应用程序。当然,这里有一个关键词是“可能”,因为目前.NET只能在Windows操作系统上运行。
注:摘自《.NET分布式编程——C#篇 》