第一章 .NET体系结构
本章内容:
编译和运行面向.NET的代码
Microsoft中间语言(Microsoft Intermediate Language,MSIL或简称IL)的优点
值类型和引用类型
数据类型化
理解错误处理和特性
程序集、.NET基类和名称空间
整本书都讲强调,c#语言不能孤立地使用而必须和.NET Framework一起考虑。C#编译器专门用于.NET,这表示用c#编写的所有代码总是在.NET Framewok 中运行。对于c#语言来说,可以得出两个重要的结论:
(1)、c#的结构和方法论反映了.NET基础方法论。
(2)在许多情况下,c#的特定语言功能取决于.NET的功能,或依赖于.NET基类。
由于种种依赖性,在开始编写c#程序前,了解.NET的体系结构和方法论就非常重要,这就是本章的目的所在。
1.1 c#与.NET的关系
c#是一种相当新的编程语言,c#的重要性体现在以下两个方面:
1、专门为与Microsoft的.NET Framework 一起使用而设计的(.NET Framework 是一个功能非常丰富的平台,可开发、部署、和执行分布式应用程序)。
2、一种基于面向对象设计方法的语言,在设计它时,Microsoft还吸取了其他所有类似语言的经验, 这些语言是近20年来面向对规则得到广泛应用后才开发出来的。
有一个很重要的问题要弄明白:c#就其本身而言只是一种语言,尽管它是用于生成面向.NET环境的代码,但它本身不是.NET的一部分。。NET支持的一些特性,c#并不支持。而c#语言支持的另一些特性,.NET却不支持(如运算符重载)!
但是,因为c#语言和.NET在一起使用,所有如果要使用c#高效的开发应用程序,理解Framework就非常重要,所以本章将介绍.NET的内涵。
1.2 公共语言运行库
.NET Framework的核心是其运行库执行环境,称为公共语言运行库(CLR)或.NET运行库。通常将在CLR控制下运行的代码称为托管代码(managed code)。
但是在CLR执行编写好的源代码(在c#中或其他语言中编写的代码)之前,需要编译它们。在.NET中,编译分为两个阶段:
(1)把源代码编译为Microsoft中间语言(IL)。
(2)CLR把IL编译为平台专用的代码。
这两个阶段的编译过程非常重要,因为Microsoft中间语言是提供.NET的许多优点的关键。
Microsoft中间语言和Java字节码共享一种理念:他们都是低级语言,语法很简单(使用数字代码,而不是文本代码),可以非常快速地转换为本地机器码。对于代码,这种精心设计得通用语法有很重要的优点:平台无关性、提高性能和语言的互操作性。
1.2.1平台无关性
首先,这意味着包含字节码指令的同一文件可以放在任意平台,运行时编译过程的最后阶段可以很轻松地完成,这样代码就可以运行在特定的平台上。换言之,编译为中间语言就可以获得.NET平台无关性,这与编译为Java字节码就会得到Java平台无关性是一样的。
注意.NET的平台无关性目前只是通留在理论范畴,因为在编写本书时,.NET的完整实现智能用于Windows平台,但是人们正在积极准备,使它可以用于其他平台(参见Mono项目,它用于实现.NET的开发源代码,参见http://www.go-mono.com/)、。
1.2.2提高性能
前面把IL和Java做了比较,实际上,IL比Java字节码的作用还要大。IL总是即时编译的(称为JIT编译),而Java字节码常常时解释性的。Java的一个缺点是,在运行应用程序时,把Java字节码转换为内部可执行代码的过程会导致性能的损失(但在最近,Java在某些平台上能进行JIT编译)。
JIT编译器并不是把整个应用程序一次编译完(这样会有很长的启动时间),而是只编译它调用的那部分代码(这是其名称由来)。代码编译过一次后,得到的本地可执行程序就存储起来,直到退出该应用程序为止,这样在下次运行这部分代码时,就不需要重新编译了。Microsoft认为这个过程要一开始就编译整个应用程序代码的效率高得多,因为任何应用程序的大部分代码实际上并不是在每次运行期间都执行。使用JIT编译器,从来都不会编译这种代码。
这解释了为什么托管代码IL代码几乎和本地及其代码的执行速度一样快,但是并没有说明为什么Microsoft认为这会提高性能。其原因是编译过程的最后一部分是在运行时进行的。JIT编译器确切地知道程序运行在什么类型的处理器上,可以利用该处理器提供的任何特性或特定的及其代码指令来优化最后的可执行代码。
传统的编译器会优化代码,但他们的优化过程是独立于运行代码的特定处理器的。这是应为传统的编译器是在发布软件之前编译为本地及其可执行的代码。即编译器不知道运行代码的处理器的类型,例如该处理器是兼容x86的处理器还是Alpha处理器,这超出了基本操作的范围。
1.2.3语言的互操作性
使用IL不仅支持平台无关性,还支持语言的互操作性。简而言之,就是能将任何一种语言编译为中间语言,编译为中间语言的代码可以与其他语言编译过来的代码进行交互操作。
那么除了c#之外,还有什么语言可以通过.NET进行交互操作呢?下面就简要讨论其他常见语言如何与.NET交互操作。
- Visual Basic 2010
Visual Basic 6在升级到Visual Basic.NET2002时,经历了一番脱胎换骨的变化,才集成到.NET Framewok的第1版中。Visual Basic语言对Visual Basic 6进行了很大的演化,也就是说,Visual Basic 6并不适合运行.NET程序。例如,它与COM(Component Object Model,组件对象模型)的高度集成,并且把事件处理程序作为源代码显示给开发人员,大多数代码隐藏不能用作源代码。另外,它不支持继承的实现,Visual Basic 6使用的标准数据类型与.NET不兼容。
- Visual C++ 2010
- COM和COM+
1.3 中间语言
1.3.1 面向对象和接口的支持
.NET的语言无关性还有一些实际的限制。中间语言在设计时就打算实现某些特殊的编程方法,这便是面向它的语言必须与编程方法兼容,Microsoft为IL选择的特定道路是传统的面向对象的编程,带有类的单一继承性。
1.3.2 不同值类型的引用类型
与其他编程语言一样,中间语言提供了许多预定义的基本数据类型。它的一个特性是值类型和引用类型之间有明显的区别。对于值类型(value type),变量直接存储其数据,而对于引用类型(reference type),变量仅存储地址,对应的数据可以在该地址中找到。
1.3.3 强数据类型
中间语言的一个重要方面是它基于强数据类型化。所有的变量都清晰地标记为属于某个特定数据类型(在中间语言中没有Visual Basic和脚本语言中的Variant数据类型)。特别是中间语言一般不允许对模糊的数据类型执行任何操作。
尽管强迫实现类型的安全性似乎会降低性能,但在许多情况下,我们从.NET提供的、依赖于类型安全的服务中获得的好处更多。这些服务包括:
语言的互操作性
垃圾收集
安全性
应用程序域
下面讨论强数据类型对.NET的这些功能非常重要的原因。
1.语言互操作性中强数据类型化的重要性
2.垃圾回收
垃圾回收器(garbage collector)用来在.NET中进行内存管理,特别是它可以恢复正在运行的应用程序需要的内存。到目前为止,Windows平台已经使用了两种技术来释放进行向系统动态请求的内存:
完全以手工方式使应用程序代码完成这些工作。
让对象维护引用计数
3.安全性
4.应用程序域
1.3.4 通过异常处理错误
1.3.5 特性的使用
1.4 程序集
程序集是包含编译好的、面向.NET Framework的代码的逻辑单元。
程序集是完全自描述性的,它是一个逻辑单元而不是物理单元。可以存储在多个文件中(动态程序集的确存储在内存中,而不是存储在文件中)。如果一个程序集存储在多个文件中,其中就会有一个包含入口点的主文件,该文件描述了程序集中的其他文件。
注意可执行代码和库代码使用相同的程序集结构。唯一的区别是可执行的程序集包含一个主程序入口点,而库程序集不包含。
程序集有两种类型:私用程序集和共享程序集
1.4.1 私有程序集
私有程序集是最简单的一种程序集类型。私有程序集一般附带在某个软件上,且只能用于该软件。附带私有程序集的常见情况是,以可执行文件或许多库的方式提供应用程序,这些库包含的代码只能用于该应用程序。
1.4.2 共享程序集
共享程序集是其他应用程序可以使用的公共库。因为其他软件可以访问共享程序集,所以苏姚采取一定的保护措施来防止一下风险:
名称冲突
程序集被同一个程序集的不同版本覆盖
1.4.3 反射
因为程序集存储了元数据,包括在程序集中定义的所有数据类型和这些类型的成员的细节,所以可以变成访问这些元数据。这个技术称为反射。
1.4.4 并行编程
1.5 .NET Framework类
至少从开发人员的角度来看,编写托管代码的最大好处是可以使用.NET基类库。NET基类是一个内容丰富的托管代码类集合,它科室完成以前要通过Windows API来完成的绝大多数任务。这些类沿用中间语言使用的对象模型,也基于单一继承性。可以从任何适用的.NET基类实例化对象,也可以从它们派生自己的类。
1.6 名称空间
名称空间是.NET避免类名冲突的一种方式。例如,名称空间可以避免下述情况:定义一个类来表示一个顾客,称此类为Customer,同时其他人也可做相同的事。
1.7 用c#创建.NET应用程序
1.7.1 创建APS.NET应用程序
1.7.2 创建Windows窗体
1.7.3 使用WPF
要运行WPF应用程序,需要在客户机上安装.NET Framework3.0、3.5或4。
1.7.4 Windows控件
1.7.5 Windows服务
1.7.6 WCF
1.7.7 Windows WF
1.8 C#在.NET 企业体系结构中的作用
1.9 小结