效地处理各种数据。 1.34完全的安全性与错误处理 语言的安全性与错误处理能力,是衡量一种语言是否优秀的重要依据。任何人都 会犯错误,即使是最熟练的程序员也不例外:忘记变量的初始化,对不属于自己管理 范围的内存空间进行修改,……。这些错误常常产生难以预见的后果。一旦这样的软 件被投入使用,寻找与改正这些简单错误的代价将会是让人无法承受的。C#的先进设 计思想可以消除软件开发中的许多常见错误,并提供了包括类型安全在内的完整的安 全性能。为了减少开发中的错误,C#会帮助开发者通过更少的代码完成相同的功能 这不但减轻了编程人员的工作量,同时更有效地避免了错误发生。 NET运行库提供了代码访问安全特性,它允许管理员和用户根据代码的I来配 置安全等级。在缺省情况下,从 Internet和 Intranet下载的代码都不允许访问任何本地 文件和资源。比方说,一个在网络上的共享目录中运行的程序,如果它要访问本地的 些资源,那么异常将被触发,它将会无情地被异常扔出去,若拷贝到本地硬盘上运 行则一切正常。内存管理中的垃圾收集机制减轻了开发人员对内存管理的负担。NET 平台提供的垃圾收集器( Garbage Collection,GC)将负责资源的释放与对象撤销时的 内存清理工作。 变量是类型安全的。C#中不能使用未初始化的变量,对象的成员变量由编译器负 责将其置为零,当局部变量未经初始化而被使用时,编译器将做出提醒;C#不支持不 安全的指向,不能将整数指向引用类型,例如对象,当进行下行指向时,C#将自动验 证指向的有效性;C#中提供了边界检查与溢出检查功能。 135版本处理技术 C#提供内置的版本支持来减少开发费用,使用C#将会使开发人员更加轻易地开发 和维护各种商业应用。 升级软件系统中的组件(模块)是一件容易产生错误的工作。在代码修改过程中 可能对现存的软件产生影响,很有可能导致程序的崩溃。为了帮助开发人员处理这些 问题,C#在语言中内置了版本控制功能。例如:函数重载必须被显式地声明,而不会 像在C艹或Java中经常发生的那样不经意地被进行,这可以防止代码级错误和保留版 本化的特性。另一个相关的特性是接口和接口继承的支持。这些特性可以保证复杂的 软件可以被方便地开发和升级。 1.36灵活性和兼容性 在简化语法的同时,C#并没有失去灵活性。尽管它不是一种无限制的语言,比如 它不能用来开发硬件驱动程序,在默认的状态下没有指针等等,但是,在学习过程中 你将发现。它仍然是那样的灵巧。 如果需要,C#允许你将某些类或者类的某些方法声明为非安全的。这样一来,你
效地处理各种数据 1.3.4 完全的安全性与错误处理 语言的安全性与错误处理能力 是衡量一种语言是否优秀的重要依据 任何人都 会犯错误 即使是最熟练的程序员也不例外 忘记变量的初始化 对不属于自己管理 范围的内存空间进行修改 这些错误常常产生难以预见的后果 一旦这样的软 件被投入使用 寻找与改正这些简单错误的代价将会是让人无法承受的 C#的先进设 计思想可以消除软件开发中的许多常见错误 并提供了包括类型安全在内的完整的安 全性能 为了减少开发中的错误 C#会帮助开发者通过更少的代码完成相同的功能 这不但减轻了编程人员的工作量 同时更有效地避免了错误发生 .NET 运行库提供了代码访问安全特性 它允许管理员和用户根据代码的 ID 来配 置安全等级 在缺省情况下 从 Internet 和 Intranet 下载的代码都不允许访问任何本地 文件和资源 比方说 一个在网络上的共享目录中运行的程序 如果它要访问本地的 一些资源 那么异常将被触发 它将会无情地被异常扔出去 若拷贝到本地硬盘上运 行则一切正常 内存管理中的垃圾收集机制减轻了开发人员对内存管理的负担 .NET 平台提供的垃圾收集器 Garbage Collection GC 将负责资源的释放与对象撤销时的 内存清理工作 变量是类型安全的 C#中不能使用未初始化的变量 对象的成员变量由编译器负 责将其置为零 当局部变量未经初始化而被使用时 编译器将做出提醒 C#不支持不 安全的指向 不能将整数指向引用类型 例如对象 当进行下行指向时 C#将自动验 证指向的有效性 C#中提供了边界检查与溢出检查功能 1.3.5 版本处理技术 C#提供内置的版本支持来减少开发费用 使用 C#将会使开发人员更加轻易地开发 和维护各种商业应用 升级软件系统中的组件 模块 是一件容易产生错误的工作 在代码修改过程中 可能对现存的软件产生影响 很有可能导致程序的崩溃 为了帮助开发人员处理这些 问题 C#在语言中内置了版本控制功能 例如 函数重载必须被显式地声明 而不会 像在 C++或 Java 中经常发生的那样不经意地被进行 这可以防止代码级错误和保留版 本化的特性 另一个相关的特性是接口和接口继承的支持 这些特性可以保证复杂的 软件可以被方便地开发和升级 1.3.6 灵活性和兼容性 在简化语法的同时 C#并没有失去灵活性 尽管它不是一种无限制的语言 比如 它不能用来开发硬件驱动程序 在默认的状态下没有指针等等 但是 在学习过程中 你将发现 它仍然是那样的灵巧 如果需要 C#允许你将某些类或者类的某些方法声明为非安全的 这样一来 你
将能够使用指针、结构和静态数组,并且调用这些非安全的代码不会带来任何其它的 问题。此外,它还提供了一个另外的东西(这样的称呼多少有些不敬)来模拟指针的 功能— delegates,代表。再举一个例子:C#不支持类的多继承,但是通过对接口的 继承,你将获得这一功能 下面谈谈兼容性。 正是由于其灵活性,C#允许与C风格的需要传递指针型参数的AP进行交互操作, DLL的任何入口点都可以在程序中进行访问。C#遵守NET公用语言规范( Common Language Specification,CLS),从而保证了C#组件与其它语言组件间的互操作性。元 数据( Metadata)概念的引入既保证了兼容性,又实现了类型安全 14小结 Microsoft. NET计划将彻底改变我们对因特网的认识,从而在这样一个网络时代彻 底改变我们的生活。软件是一种服务,技术是我们的仆人,时间与地点将不再是我们 面前的障碍。建立在CLR与类库基础上的NET框架是NET平台的核心组件之一,这 为软件的可移植性与可扩展能力奠定了坚实的基础,并为C#语言的应用创造了良好的 环境 C#是NET平台的通用开发工具,它能够建造所有的NET应用。其固有的特性保 证了它是一种高效、安全、灵活的现代程序设计语言。从最普通的应用到大规模的商 业开发,C#与NET平台的结合将为你提供完整的解决方案。 在本章中,我们提出了与NET以及与C#语言相关的一些概念,例如CLR、VOS 和GC,也许你是初次接触它们,但不用担心,在以后的各章中我们将详细地介绍这些 相关的概念与知识,相信通过学习,你将能够迅速掌握它们,并熟练地运用它们提供 的各种特性。 复习题 (1)什么是NET? (2)简要说明NET战略的意义。 (3)NET的核心组件包括哪些? (4)C#与其它语言相比有哪些突出特点?
将能够使用指针 结构和静态数组 并且调用这些非安全的代码不会带来任何其它的 问题 此外 它还提供了一个另外的东西 这样的称呼多少有些不敬 来模拟指针的 功能 delegates 代表 再举一个例子 C#不支持类的多继承 但是通过对接口的 继承 你将获得这一功能 下面谈谈兼容性 正是由于其灵活性 C#允许与 C 风格的需要传递指针型参数的 API 进行交互操作 DLL 的任何入口点都可以在程序中进行访问 C#遵守.NET 公用语言规范 Common Language Specification CLS 从而保证了 C#组件与其它语言组件间的互操作性 元 数据 Metadata 概念的引入既保证了兼容性 又实现了类型安全 1.4 小 结 Microsoft.NET 计划将彻底改变我们对因特网的认识 从而在这样一个网络时代彻 底改变我们的生活 软件是一种服务 技术是我们的仆人 时间与地点将不再是我们 面前的障碍 建立在 CLR 与类库基础上的.NET 框架是.NET 平台的核心组件之一 这 为软件的可移植性与可扩展能力奠定了坚实的基础 并为 C#语言的应用创造了良好的 环境 C#是.NET 平台的通用开发工具 它能够建造所有的.NET 应用 其固有的特性保 证了它是一种高效 安全 灵活的现代程序设计语言 从最普通的应用到大规模的商 业开发 C#与.NET 平台的结合将为你提供完整的解决方案 在本章中 我们提出了与.NET 以及与 C#语言相关的一些概念 例如 CLR VOS 和 GC 也许你是初次接触它们 但不用担心 在以后的各章中我们将详细地介绍这些 相关的概念与知识 相信通过学习 你将能够迅速掌握它们 并熟练地运用它们提供 的各种特性 复习题 1 什么是.NET 2 简要说明.NET 战略的意义 3 .NET 的核心组件包括哪些 4 C#与其它语言相比有哪些突出特点
第二章运行环境——全面了解NET C#运行在NET平台之上,其各种特性与NET密切联系。它没有自己的运行库, 许多强大的功能均来自NET平台的支持。因此,要想真正掌握C#首先必须了解NET 本章将向你介绍C#的运行环境,重点放在NET公用语言运行时环境与公用语言规范 上,最后介绍了NET的开发工具 2.1NET结构 NET包括四个组成部分: VOS类型系统 元数据 公用语言规范 ●虚拟执行系统 下面分别对它们进行简要介绍 2.1.1虚拟对象系统 NET跨语言集成的特性来自于虚拟对象系统(VOS)的支持。 在不同语言间进行代码复用和应用集成中所遇到的最大问题,是不同语言类型系 统间的相容性问题。可以想象,不同的语言虽然语法结构大体相同,但数据类型与语 言环境本身的各种特点联系紧密,很难想象一种解释性的语言所拥有的数据类型会与 种编译语言相同,而即使相同的数据类型在不同的语言环境中表示的意义也存在差 别。例如,同样是整数类型,在 MSSQL中的长度是32位,而在VB中却是16位,至 于日期时间与字符串类型在这方面的区别就更加明显了 vOS的建立就是为了改变这种状况。它既支持过程性语言也支持面向对象的语言, 同时提供了一个类型丰富的系统来容纳它所支持的各种语言的特性。它在最大程度上 屏蔽了不同语言类型系统间的转换,使程序员能够随心所欲地选择自己喜欢的语言(当 然,这种语言必须支持NET应用)从事开发,保证了不同语言间的集成 对于过程性语言,它描述了值的类型并指定了类型的所有值必须遵守的规则;在 面向对象的语言方面,它统一了不同编程语言的对象模型。每一个对象在VOS中都被 唯一标识以与其它对象相区别
第二章 运行环境 全面了解.NET C#运行在.NET 平台之上 其各种特性与.NET 密切联系 它没有自己的运行库 许多强大的功能均来自.NET 平台的支持 因此 要想真正掌握 C#首先必须了解.NET 本章将向你介绍 C#的运行环境 重点放在.NET 公用语言运行时环境与公用语言规范 上 最后介绍了.NET 的开发工具 2.1 .NET 结构 .NET 包括四个组成部分 z VOS 类型系统 z 元数据 z 公用语言规范 z 虚拟执行系统 下面分别对它们进行简要介绍 2.1.1 虚拟对象系统 .NET 跨语言集成的特性来自于虚拟对象系统 VOS 的支持 在不同语言间进行代码复用和应用集成中所遇到的最大问题 是不同语言类型系 统间的相容性问题 可以想象 不同的语言虽然语法结构大体相同 但数据类型与语 言环境本身的各种特点联系紧密 很难想象一种解释性的语言所拥有的数据类型会与 一种编译语言相同 而即使相同的数据类型在不同的语言环境中表示的意义也存在差 别 例如 同样是整数类型 在 MSSQL 中的长度是 32 位 而在 VB 中却是 16 位 至 于日期时间与字符串类型在这方面的区别就更加明显了 VOS 的建立就是为了改变这种状况 它既支持过程性语言也支持面向对象的语言 同时提供了一个类型丰富的系统来容纳它所支持的各种语言的特性 它在最大程度上 屏蔽了不同语言类型系统间的转换 使程序员能够随心所欲地选择自己喜欢的语言 当 然 这种语言必须支持.NET 应用 从事开发 保证了不同语言间的集成 对于过程性语言 它描述了值的类型并指定了类型的所有值必须遵守的规则 在 面向对象的语言方面 它统一了不同编程语言的对象模型 每一个对象在 VOS 中都被 唯一标识以与其它对象相区别
2.1.2元数据 元数据是对VOS中类型描述代码的一种称呼。在编译程序将源代码转换成为中间 代码时,它将自动生成,并与编译后的源代码共同包含在二进制代码文件中。元数据 携带了源代码中类型信息的描述,这在一定程度上解决了版本问题:程序使用的类型 描述与其自身绑定在一起。 在CLR定位与装载类型时,系统通过读取并解析元数据来获得应用程序中的类型 信息,JT编译器获得加载的类型信息后,将中间语言代码翻译成为本地代码,在此基 础上根据程序或用户要求建立类型的实例。由于整个过程中,CLR始终根据元数据建 立并管理对应特定应用程序的类型,从而保证了类型安全性。 此外,元数据在解决方法的调用,建立运行期上下文界限等方面都有着自己的作 用。而关于元数据的一切都由NET在后台完成。 2.1.3公用语言规范 公用语言规范( Common Language Specification,CLS),是CLR定义的语言特性 集合,主要用来解决互操作问题。如果一个类库遵守CLS,那么同样遵守CLS规范的 其它编程语言将能够使用它的外部可见项。详细的内容见本章第二节 2.14虚拟执行系统 虚拟执行系统( Visual Execution System,VES)是VOS的实现,它用来驱动运行 环境。元数据的生成与使用、公用语言规范的满足性检查以及应用程序执行过程中的 内存管理均由它来完成。具体说来,ⅤES主要完成以下功能 装入中间代码。 使用JT将中间代码转换为本地码 装入元数据 代码管理服务——包括垃圾收集器和异常处理 定制与调试服务。 线程和环境管理 2.2公用语言运行时环境与公用语言规范 了解了NET的结构之后,我们该看看NET利用其结构为我们创造的运行环境一 一公用语言运行时环境。它是C#及其它支持NET平台的开发工具的运行基础。具体 来说,它为我们的应用提供了以下益处 跨语言集成的能力。 跨语言异常处理。 内存管理自动化
2.1.2 元数据 元数据是对 VOS 中类型描述代码的一种称呼 在编译程序将源代码转换成为中间 代码时 它将自动生成 并与编译后的源代码共同包含在二进制代码文件中 元数据 携带了源代码中类型信息的描述 这在一定程度上解决了版本问题 程序使用的类型 描述与其自身绑定在一起 在 CLR 定位与装载类型时 系统通过读取并解析元数据来获得应用程序中的类型 信息 JIT 编译器获得加载的类型信息后 将中间语言代码翻译成为本地代码 在此基 础上根据程序或用户要求建立类型的实例 由于整个过程中 CLR 始终根据元数据建 立并管理对应特定应用程序的类型 从而保证了类型安全性 此外 元数据在解决方法的调用 建立运行期上下文界限等方面都有着自己的作 用 而关于元数据的一切都由.NET 在后台完成 2.1.3 公用语言规范 公用语言规范 Common Language Specification CLS 是 CLR 定义的语言特性 集合 主要用来解决互操作问题 如果一个类库遵守 CLS 那么同样遵守 CLS 规范的 其它编程语言将能够使用它的外部可见项 详细的内容见本章第二节 2.1.4 虚拟执行系统 虚拟执行系统 Visual Execution System VES 是 VOS 的实现 它用来驱动运行 环境 元数据的生成与使用 公用语言规范的满足性检查以及应用程序执行过程中的 内存管理均由它来完成 具体说来 VES 主要完成以下功能 z 装入中间代码 z 使用 JIT 将中间代码转换为本地码 z 装入元数据 z 代码管理服务 包括垃圾收集器和异常处理 z 定制与调试服务 z 线程和环境管理 2.2 公用语言运行时环境与公用语言规范 了解了.NET 的结构之后 我们该看看.NET 利用其结构为我们创造的运行环境 公用语言运行时环境 它是 C#及其它支持.NET 平台的开发工具的运行基础 具体 来说 它为我们的应用提供了以下益处 z 跨语言集成的能力 z 跨语言异常处理 z 内存管理自动化
强化的安全措施 版本处理技术 ●组件交互的简化模型 2.2.1理解CLR NET提供了一个运行时环境,叫做公用语言运行时,它管理着代码的执行,并使 得开发过程变得更加简单。这是一种可操控的执行环境,其功能通过编译器与其它工 具共同展现,你的代码将受益于这一环境。依靠一种以运行时为目标的(指完全支持 运行时环境的)编译器所开发的代码叫做可操控代码。它得益于可操控环境的各种特 性:跨语言集成、跨语言异常处理、增强的安全性、版本处理与开发支持、简单的组 件交互模型以及调试服务。为了使运行时环境能够向可操控代码提供服务,语言编译 器需要产生一种元数据,它将提供在你使用语言中的类型、成员、引用的信息。元数 据与代码一起存储,每个可加载的αLR映像均包含了元数据。运行时环境使用元数据 定位并载入类,在内存中展开对象实例,解决方法调用,产生本地代码,强制执行安 全性,并建立运行时环境的边界。 运行时环境自动处理对象的展开与引用,当它们不再使用时负责它们的释放。被 运行时环境进行这样的生命期管理的对象被称为可操控代码。自动内存管理消除了内 存溢出,同时也解决了其它一些常见的语法错误。如果你的代码是可操控的,你仍然 可以在需要的时候使用非可控代码,或者在你的NET应用中同时使用可控与非可控代 码。由于语言编译器支持他们自己的类型,比如一些原始类型,你可能并不总是知道 (也不必知道)你的数据是否是可控的。 CLR使设计跨语言的组件与应用变得更加容易。以不同语言设计的对象能够彼此 间进行通信,并且它们的行为能够紧密地综合与协调。举个例子,你定义了一个类 然后可以在另一种不同的语言中从该类中派生了一个类或者调用它其中的一个方法。 你也可以向另一种语言中类的方法传递该类的一个实例。这种跨语言的集成之所以可 能,因为以运行时间为目标的语言编译器与工具使用一种运行时间所定义的公用类型 系统,他们遵守运行时的规则(公用语言规范)来定义新的类型,生成、使用、保持 并绑定类型 作为元数据的一部分,所有可控组件携带了关于它们所依赖的组件与资源的信息。 运行时环境使用这些信息来保证你的组件或应用具有需要的所有东西的特定版本,其 结果是你的代码将不会因为版本冲突而崩溃。注册信息与状态数据不再保存在难以建 立与维护的注册表中,你所定义的类型及附属信息作为元数据被保存,这使得复制与 移动组件的复杂程度得到降低 编译工具用他们自己的方式向开发人员展现CLR的功能。这意味着运行时间的 些特性可能在不同的语言中的表现形式将会有所不同。你怎样体验运行时的特性将取 决于你所使用的语言,比如说,如果你是一位VB开发人员,你可能注意到在运行时 环境的帮助下,VB语言比以前具有更多的面向对象的特性
z 强化的安全措施 z 版本处理技术 z 组件交互的简化模型 2.2.1 理解 CLR .NET 提供了一个运行时环境 叫做公用语言运行时 它管理着代码的执行 并使 得开发过程变得更加简单 这是一种可操控的执行环境 其功能通过编译器与其它工 具共同展现 你的代码将受益于这一环境 依靠一种以运行时为目标的 指完全支持 运行时环境的 编译器所开发的代码叫做可操控代码 它得益于可操控环境的各种特 性 跨语言集成 跨语言异常处理 增强的安全性 版本处理与开发支持 简单的组 件交互模型以及调试服务 为了使运行时环境能够向可操控代码提供服务 语言编译 器需要产生一种元数据 它将提供在你使用语言中的类型 成员 引用的信息 元数 据与代码一起存储 每个可加载的 CLR 映像均包含了元数据 运行时环境使用元数据 定位并载入类 在内存中展开对象实例 解决方法调用 产生本地代码 强制执行安 全性 并建立运行时环境的边界 运行时环境自动处理对象的展开与引用 当它们不再使用时负责它们的释放 被 运行时环境进行这样的生命期管理的对象被称为可操控代码 自动内存管理消除了内 存溢出 同时也解决了其它一些常见的语法错误 如果你的代码是可操控的 你仍然 可以在需要的时候使用非可控代码 或者在你的.NET 应用中同时使用可控与非可控代 码 由于语言编译器支持他们自己的类型 比如一些原始类型 你可能并不总是知道 也不必知道 你的数据是否是可控的 CLR 使设计跨语言的组件与应用变得更加容易 以不同语言设计的对象能够彼此 间进行通信 并且它们的行为能够紧密地综合与协调 举个例子 你定义了一个类 然后可以在另一种不同的语言中从该类中派生了一个类或者调用它其中的一个方法 你也可以向另一种语言中类的方法传递该类的一个实例 这种跨语言的集成之所以可 能 因为以运行时间为目标的语言编译器与工具使用一种运行时间所定义的公用类型 系统 他们遵守运行时的规则 公用语言规范 来定义新的类型 生成 使用 保持 并绑定类型 作为元数据的一部分 所有可控组件携带了关于它们所依赖的组件与资源的信息 运行时环境使用这些信息来保证你的组件或应用具有需要的所有东西的特定版本 其 结果是你的代码将不会因为版本冲突而崩溃 注册信息与状态数据不再保存在难以建 立与维护的注册表中 你所定义的类型及附属信息作为元数据被保存 这使得复制与 移动组件的复杂程度得到降低 编译工具用他们自己的方式向开发人员展现 CLR 的功能 这意味着运行时间的一 些特性可能在不同的语言中的表现形式将会有所不同 你怎样体验运行时的特性将取 决于你所使用的语言 比如说 如果你是一位 VB 开发人员 你可能注意到在运行时 环境的帮助下 VB 语言比以前具有更多的面向对象的特性