第一章.NET体系结构

1.1 C#.NET的关系

C#是一种相当新的编程语言,C#的重要性体现在:

l         它是专门为Microsoft.NET Framework一起使用而设计的

l         它是一种基于现代面向对象设计方法的语言.

C#本身只是一门语言,尽管他是用于生成面向.NET环境的代码,但它本身并不是.NET的一部分.,NET支持的一些特性,C#并不支持.C#语言支持的一些特性,.NET并不支持(例如运算符重载)

1.2公共语言运行库(Common Language Runtime)

.NET Framework的核心是其运行库的执行环境,称为公共语言运行库或.NET运行库.通常在CLR的控制下运行的代码称为托管代码(managed code)

但是,CLR执行开发的源代码前,需要首先编译它们..NET,编译分为两个阶段:

(1)    把源代码编译为Microsoft中间语言(Intermidia Language)

(2)    CLRIL编译为平台专用的代码

托管代码的优点

Microsoft中间语言与Java字节代码共享一种理念:它们都是一种低级语言,语法简单,可以快速的转换为内部机器码.

1.       平台无关性(目前只是一种可能)

2.       提高性能(即时编译,Just In Time,JIT)

提高性能的原因,编译过程的最后一个阶段是在运行时进行的,此时编译器确切的知道程序运行在什么类型的处理器上,可以利用该处理器提供的任何特性或者特定的机器代码指令来优化最后的可执行代码

3.       语言的互操作性

简而言之,就是能将任何一种语言编译为中间代码,编译好的代码可以与从其他语言编译过来的代码进行交互操作.

1.3 详细介绍中间语言

面向.NET的所用语言在逻辑上都支持IL的以下几个主要特征:

l         面向对象和使用接口

l         值类型和引用类型的巨大差别

l         强数据类型

l         使用异常来处理错误

l         使用特性(Attribute)

1.3.1面向对象和接口的支持

IL在设计时就打算要实现某些特定的编程方法,MicrosoftIL选择的特定道路是传统的面向对象的编程,带有类的单一继承性.除此之外,IL还引入了接口的概念..NET接口与COM接口不同,它们不需要支持任何COM基础结构.但他们与COM接口共享下述理念:提供一个契约,实现给定接口的类必须提供该接口制定的方法和属性的实现方式.

语言互操作性的概念,语言互操作性的真正含义是用一种语言编写的类应能直接与用另一种语言编写的类进行通信.特别是:

 用一种语言编写的类英能继承用另一种语言编写的类

 一个类应能包含另一个类的实例.而不管它们是用什么语言编写的

 一个对象应能直接调用用其他语言编写的另一个对象的方法

 对象或其引用应能在方法之间传递

对不同语言之间调用方法时,应能在调试器调试这些方法的调用

1.3.2相异值类型和引用类型

值类型与引用类型存在明显区别.对于值类型,变量直接保存数据,而对于引用类型,变量仅保存地址,对应的数据可以在该地址中找到.

中间语言也有数据存储的规范:引用类型的实例总存储在一个名为托管堆的内存区域中,值类型一般存储在堆栈中(如果值类型在 引用类型中声明为字段,则内联存储在堆中)

1.3.3强数据类型

IL的一个重要方面是它基于强数据类型

.NET提供的,依赖于类型安全的服务:

 语言的互操作性

 垃圾收集

 安全性

 应用程序域

1.       语言互操作性中强数据类型的重要性

如果类派生于其他类.或包含其他类的实例,就需要知道其他类使用的所有数据类型,这就是强数据类型非常重要的原因.

(1)    通用类型系统(Common Type System,CTS)

CTS定义了可以在IL中使用的预定义的数据类型,所有面向.NET Framework的语言都可以生成最终基于这些类型的编译代码.

CTS不仅指定了基本数据类型,而且还定义了一个内容丰富的类型层次系统

(2)    公共语言规范(Common Language Specification,CLS)

CLSCTS一起确保语言的互操作性.CLS是一个最低标准,所有面向.NET的编译器都必须支持他.

CLS的两种工作方式:首先是各个编译器的功能不必强大到支持.NETd的所有功能;其次它提供如下保证:如果限制类只能使用CLS兼容的特性,就要保证用其他语言编写的代码可以使用这个类.

这种方式的优点是使用CLS兼容特性的限制只适用于公共的或受保护的类成员和公共类.

2.       垃圾收集

垃圾收集器用来在.NET中进行内存管理.方法是所有动态请求的内存都分配到堆上(但在.NET,CLR维护他自己的托管堆,以供.NET应用程序继续使用),.NET检测到给定进程的托管堆已满,需要清理时,就调用垃圾收集器.垃圾收集器处理目前代码中的所有的变量,检查对存储在托管堆上的对象的引用,确定哪些对象可以从代码中访问.

之所以使用垃圾收集器,是因为IL以用来处理进程.其规则要求,第一,不能引用已用的对象,除非复制已用的引用(?不太明白,有待进一步思考).第二,中间语言是类型安全的语言,其含义是如果存在对对象的任何引用,该引用就有足够的信息来确定对象的类型.

垃圾收集器是不确定的,但可以重写这个过程在代码中调用.

3.       安全性

.Net提供的安全机制是基于代码的安全机制,它建立在代码实际执行的任务和代码的可信程度上.CLR可以在运行代码前检查IL,以确定是否有需要的安全权限..NET还提供了一种机制,可以在运行代码前制定代码需要什么安全权限.

4.       应用程序域

主要用于减少运行应用程序的系统开销,这些应用程序需要与其他程序分离开来,但同时还要彼此通信.

到现在位置,鼓励代码的唯一方式是通过进程实现的,而他有一大缺点,性能.

应用程序域是分离组件的一种方式,其方法是把任何一个进程分解到多个应用程序域中,每个应用程序域大致对应一个程序,执行的每个线程都运行在一个具体的应用程序域中.

具体的优点是什么,与COM组件相比。运行在同一个进程中不同应用程序域的进程如何通信?http://www.newasp.net/tech/net/13775.html 参考网址

1.3.4通过异常方法处理错误

.NETFramework可以根据异常使用相同的机制处理错误情况,它支持finally

1.3.5特性的使用

特性最初是为了在程序中提供与某些项相关的额外信息,以供编译器使用. .NET中建立了一种特性机制,通过该机制可以在源代码中定义自己的特性.这些自定义的特性将和对应数据类型或方法的元数据一起,对于文档说明书非常有用,它们和反射技术一起使用,以根据特性执行编程任务.另外,.特性也是语言无关的.

1.4程序集

程序集(Assembly)是包含编译好的、面向.NET Framework的代码的逻辑单元。程序集是完全自我描述性的。也是一个逻辑单元,而不是一个物理单元,它可以存储在多个文件中,其中就会有一个包含入口点的主文件,该文件描述了程序集中的其它文件。

可执行代码和库代码使用相同的程序集结构。唯一的区别是可执行的程序集包含一个主程序入口点。

程序集的一个重要特性是它们包含的元数据描述了对应代码中定义的类型和方法。程序集也包含描述程序集本身的元数据,这种程序集元数据包含在一个称为程序集清单的区域中,可以检查程序集的版本及其完整性。(ildasm是一个基于Windows的实用程序,可以用于检查程序集的内容,包括程序集清单和元数据)

程序集包含程序的元数据,表示调用给定程序集中的代码的应用程序或其它程序集不需要制定注册表或其他数据源,以便确定如何使用该程序集。

程序集有两种类型:共享程序集和私有程序集

1.4.1私有程序集

它是最简单的一种程序集类型。私有程序集一般附带在某些软件上,只能用于该软件中。附带私有程序集的常见情况是,以可执行文件或许多库的方式提供应用程序,这些库包含的代码只能应用于该应用程序。私有程序集完全是自含式的,只需“0影响(Xcopy)安装”

1.4.2共享程序集

共享程序集是其他应用程序可以使用的公共库,它主要有以下两种风险:

l         名称冲突

l         程序集被同一个程序集不同的版本覆盖。

这些问题的解决办法是吧共享程序集放在文件系统的一个特定的子目录树中,称为全局程序集高速缓存(GAC

为了避免名称冲突,共享程序集应根据私有密钥加密法制定一个名称。该名称称为强名(strong name),并保证其唯一性,他必须由要引用共享程序集的应用程序来引用。

与覆盖程序集相关的问题,可以通过在程序集清单中指定版本信息来解决,也可以通过同时安装来解决。

1.4.3反射

程序集存储了元数据,包括在程序集中定义的所有类型和这些类型的所有的成员的细节,故可以变成访问这些数据,这个技术称为反射。它常常用于获取特性的详细信息,也可以把反射用于其他目的,例如实例化类或调用方法的一种间接方式,如果把方法上的类名指定为字符串,就可以选择类来实例化方法,以便在运行时调用,而不是在编译时调用。