65.9K
CodeProject 正在变化。 阅读更多。
Home

开发标准

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (3投票s)

2008 年 1 月 13 日

CPOL

13分钟阅读

viewsIcon

24192

本文介绍了 .NET 软件开发的标准方法

引言

微软已获得 ECMA 和 ISO/IEC 对 C# 和 CLI 的行业标准认证。这对于微软和 .NET 平台来说是一个非常重要的步骤,因为它增强了新 .NET 平台的可信度,并吸引了更大一部分技术行业采用 .NET 作为其开发平台。一些公司和政府组织只使用 ISO 认证的技术;例如,在澳大利亚,根据澳大利亚政府的规定,任何 ISO 认证的也都被视为澳大利亚标准。许多学术机构现在将有兴趣教授标准 C#。拥有开放行业标准规范的另一个主要成果是 .NET 平台可以移植到其他平台,如 Linux 和 UNIX;最好的例子是 Ximian 的 Mono 项目——它是一个基于 ECMA 批准的 C# 和 CLI 公共领域规范的 UNIX 和 Linux 上 .NET 平台的开源实现。微软向 ECMA 提交了规范,ECMA 又通过 ISO 快速推进了它们。在此过程中,微软将核心 C#/CLI 平台的所有知识产权发布到公共领域。任何人都不需要许可证来实现 C#/CLI。这也有助于所有人更好地理解 C# 和 CLI 的实现,它们是 .NET 平台的核心。

微软已在其所有受支持的硬件平台上为其所有操作系统套件(不包括 Microsoft Windows 95 及更早版本)实现了 .NET Framework。对于手持设备和小型设备,微软已发布了 .NET 的紧凑框架。但是,还有各种其他实现在非 Microsoft Windows 平台上开发。继 Microsoft .NET 之后,最流行的实现是 Linux 上的开源“Mono”项目。微软已将 .NET Framework 的几乎所有源代码以共享源代码公共语言基础架构 (SSCLI) 的名义发布给 FreeBSD 和 Mac OS。

传统开发与 .NET 开发的区别

在传统编程语言中,程序的源代码被编译成特定平台的汇编语言,然后是机器语言代码。随后,程序所需的库代码被链接到其中。最后,操作系统在用户需要时执行程序。整个过程如下图所示

在 .NET Framework 存在的情况下,程序不会被编译成原生机器可执行代码;而是被编译成一种称为 Microsoft 中间语言 (MSIL) 或通用中间语言 (CIL) 的中间语言代码。.NET 公共语言运行时 (CLR) 然后在运行时将此中间代码转换为机器可执行代码。优化在运行时进行。程序也不直接调用操作系统 API;而是将此任务委托给 CLR,CLR 代表程序执行所需的操作并将操作结果返回给程序。CLR 还代表程序执行内存管理、垃圾回收、安全和线程管理。.NET Framework 随附支持通用代码库的面向对象框架,称为 .NET Framework 类库 (FCL),以方便进行通用操作。因此,.NET 管理应用程序的整体执行。这就是在 .NET Framework 上运行的代码有时被称为托管代码的原因。整个过程如下图所示。请注意,只有 CLR(以及因此 .NET Framework,而不是用户应用程序)与平台和操作系统进行交互和耦合。

.NET 平台(框架)的基本组件是

公共语言运行时 (CLR)

.NET Framework 最重要的部分是 .NET 公共语言运行时 (CLR),简称 .NET Runtime。它是一个位于操作系统之上的框架层,负责处理/管理 .NET 应用程序的执行。我们的 .NET 程序不直接与操作系统通信,而是通过 CLR 通信。

MSIL(Microsoft 中间语言)代码

当我们使用任何 .NET 兼容语言(如 C#、VB.NET、C++ .NET)编译我们的 .NET 程序时,它不会转换为可执行二进制代码,而是转换为 CLR 可理解的中间代码,简称 MSIL 或 IL。MSIL 是一种独立于操作系统和硬件的代码。当程序需要执行时,此 MSIL 或中间代码会转换为二进制可执行代码,称为本机代码。IL 的存在使得跨语言关系成为可能,因为所有 .NET 兼容语言都会生成相似的标准 IL 代码。

即时编译器 (JITer)

当我们的 IL 编译代码需要执行时,CLR 调用 JIT 编译器,这些编译器将 IL 代码编译为特定机器和操作系统的本机可执行代码(.exe.dll)。JITer 在许多方面与传统编译器不同,因为正如其名称所示,它们仅在需要时才将 IL 编译为本机代码,例如,当调用函数时,函数的 IL 主体会转换为本机代码;正好在需要时。因此,特定运行中未使用的代码部分不会转换为本机代码。如果一些 IL 代码已转换为本机代码,那么下次需要使用时,CLR 会使用相同的副本而无需重新编译。因此,如果程序运行一段时间,就不会有任何即时性能损失。由于 JITer 在运行时确切了解处理器和操作系统,因此它们可以极其高效地优化代码,从而产生非常健壮的应用程序。此外,由于 JITer 知道可执行代码的确切当前状态,因此它们还可以通过内联小型函数调用来优化代码(例如,在循环中调用小型函数时替换其主体,从而节省函数调用时间)。尽管微软表示 C# 和 .NET 在效率、执行速度方面不与 C++ 等语言竞争,但在某些情况下,当程序长时间运行(例如 Web 服务器)时,JITer 可以使您的代码甚至比 C++ 代码更快。

框架类库 (FCL)

.NET Framework 为常见、常用任务提供了大量框架(或基础)类库 (FCL)。FCL 包含数千个类,用于提供对 Windows API 和常见函数的访问,如字符串操作、常见数据结构、IO、流、线程、安全、网络编程、Windows 编程、Web 编程、数据访问等。它简直是有史以来随任何开发环境或编程语言提供的最大标准库。该库最好的部分是它们遵循极其高效的面向对象设计(设计模式),使其访问和使用非常简单和可预测。您可以在程序中使用 FCL 中的类,就像使用任何其他类一样,甚至可以对它们应用继承和多态。

公共语言规范 (CLS)

前面我们使用了“支持 .NET 的语言”这个术语,并指出所有支持 .NET 的语言都可以使用 CLR 和 FCL。但是,是什么让一种语言成为“支持 .NET 的语言”呢?答案就是公共语言规范 (CLS)。微软发布了一小套规范,每种语言都必须满足这些规范才能被认定为支持 .NET 的语言。由于 IL 是一种非常丰富的语言,一种语言不一定需要实现所有 IL 功能,而是满足其中的一小部分,即 CLS,才能被认定为支持 .NET 的语言,这就是为什么现在有如此多语言(过程式和面向对象)在 .NET 保护伞下运行的原因。CLS 主要解决语言设计问题,并制定了一些标准,例如不应有全局函数声明、没有指针、没有多重继承等等。这里需要注意的重要一点是,如果您的代码保持在 CLS 边界内,则您的代码保证可以在任何其他 .NET 语言中使用。

通用类型系统 (CTS)

.NET 还定义了通用类型系统 (CTS)。与 CLS 类似,CTS 也是一组标准。CTS 定义了 IL 理解的基本数据类型。每个 .NET 兼容语言都应该将其数据类型映射到这些标准数据类型。这使得两种语言可以通过相互传递/接收参数来进行通信。例如,CTS 定义了一个 Int32 类型,一个 32 位(4 字节)的整数数据类型,C# 通过 int 映射它,VB.Net 通过其 Integer 数据类型映射它。

垃圾收集器 (GC)

CLR 还包含垃圾收集器 (GC),它在一个低优先级线程中运行,检查未引用的动态分配内存空间。如果它发现一些不再被任何变量/引用引用的数据,它会回收它,并将占用的内存返回给操作系统;以便在需要时供其他程序使用。标准垃圾收集器的存在使程序员无需跟踪悬空数据。

Microsoft.NET 中的软件开发和执行流程

在 .NET 开发环境中,开发人员可以使用任何 .NET 兼容编程语言(如 C#、VB.NET、J#、C++.NET 等)编写代码。事实上,应用程序的各种模块、组件、项目都可以用不同的基于 .NET 的编程语言编写和编译。所有这些组件都编译成 .NET CLR 可理解的相同中间语言代码(MSIL 或 CIL)。

在运行时,.NET 程序集(已编译的 IL 代码)被转换为本机机器代码并由 CLR 执行。

Microsoft .NET 与基于 Java 的平台 (J2EE) 的比较

在根级别架构和组件方面,Microsoft .NET 和 J2EE 平台非常相似。两者都是基于虚拟机的架构,CLR 和 Java 虚拟机 (JVM) 作为底层虚拟机来管理和执行程序。两者都代表程序提供内存、安全和线程管理,并且都试图将应用程序与执行环境(操作系统和物理机)解耦。两者基本上都以基于 Web 的应用程序,特别是基于 XML 的 Web 服务为目标。两者都提供对内存的托管访问,并且不允许其托管应用程序直接访问内存。

然而,这两个虚拟机的架构和设计存在一些对比。Microsoft .NET 框架的架构与 Microsoft Windows 操作系统耦合更紧密,这使得在各种操作系统和物理机上实现它变得困难。另一方面,Java 几乎可在所有主要平台上使用。从另一方面看,J2EE 架构和 JVM 与 Java 编程语言耦合更紧密,而 Microsoft .NET 从一开始就设计用于支持语言独立性和语言集成。Microsoft .NET 在组件开发和集成方面比 Java 涵盖得更详细。.NET 的版本控制策略简直是软件开发史上实现最好的版本控制解决方案。Java 获得了 Sun、IBM、Apache 和 Oracle 等行业巨头的支持,而 Microsoft .NET 则获得了微软、英特尔和惠普等巨头的支持。

Microsoft .NET 用于软件开发

世界各地的大部分软件开发都是在 Microsoft Windows 操作系统上进行的,并且是为 Microsoft Windows 操作系统开发的。.NET 现在是 Microsoft Windows 操作系统的标准软件开发环境。它极大地简化了 Windows、基于 Web 的数据访问应用程序、组件、控件和 Web 服务的开发。.NET 具有 XML 配置、反射和属性等惊人的功能,可简化整个软件开发生命周期。最后,.NET 由 Microsoft Visual Studio 集成开发环境支持;这是任何软件开发环境中最好的 IDE。Visual Studio .NET (VS.NET) 支持软件开发的所有领域,从项目创建到调试和安装。

Microsoft .NET 平台的缺点

.NET 平台最大的缺点是它仍然是微软的专有技术。它与 Microsoft Windows 操作系统耦合更紧密,并且只在 Microsoft Windows 上成功实现。Microsoft .NET 桌面应用程序只能在 Microsoft Windows 上运行,基于 Web 的应用程序和 Web 服务只能部署在 Microsoft Internet Information Server (IIS) 上。由于 .NET 框架包含大量实用程序、组件和框架类库,可下载框架的大小相当大(25MB,而 JVM 为 5MB)。并非所有类型的应用程序都可以用 .NET 托管应用程序编写,例如,您不能在托管应用程序中编写 CLR 或操作系统。托管 .NET 应用程序的启动和运行速度比传统的 Win32 应用程序慢一些。托管 .NET 应用程序的编译代码更容易反编译回源代码。

与 C++ 相比,.NET 和 Java 程序效率低下的说法有多真实?

托管 .NET 和 Java 程序的启动速度确实比传统的 C++ 程序慢,因为 .NET 中涉及将 CLR 托管到托管应用程序进程中,而 Java 中则是在新进程中启动 JVM。在程序执行的初始阶段,执行速度也会稍慢,因为中间代码在运行时即时翻译成机器代码。但随着程序反复运行各个部分,执行速度也会加快。由于 CLR 和 JVM 比静态 C++ 编译器更有效地优化代码,因此在程序启动一段时间后,当大部分代码都被翻译后,程序的执行速度实际上可能会更快。因此,从长远来看,与 C++ 相比,基于 .NET 和 Java 的程序不应该效率低下。我们这里使用“应该”,因为实际性能取决于特定的实现和实现策略。

在 .NET 中使用 COM 组件

.NET 不鼓励直接在托管应用程序内部使用 COM 组件!尽管 .NET Framework 包含允许 COM 组件在 .NET 应用程序内部无缝使用的实用程序。它是如何做到的?诸如 TlbImp 之类的 .NET 实用程序会为 COM 组件生成包装 .NET 程序集,该程序集向客户端提供与 COM 组件公开的相同的调用接口。在包装器方法内部,它调用 COM 组件的实际方法并将结果返回给调用者。生成的包装 .NET 程序集称为“运行时可调用包装器”或 RCW。

要在 Visual Studio .NET 项目中使用 COM 组件,您需要在解决方案资源管理器窗口中,在项目节点的“引用”节点下添加对 COM 组件的引用。Visual Studio .NET 的优点在于,它允许您以与添加对 .NET 程序集的引用完全相同的方式添加对 COM 组件的引用。Visual Studio .NET 会自动为引用的 COM 组件创建运行时可调用包装程序集。

要添加对 COM 组件的引用,右键单击解决方案资源管理器中项目节点下的“引用”节点,然后选择“添加引用...”选项。它将显示一个用户界面屏幕,您可以在其中浏览目标 COM 组件。选择组件后,按“选择”按钮,然后按“确定”。这将在项目的“引用”子树中添加一个新的引用节点。通过选择添加的引用节点,您可以从属性窗口编辑其属性。

将 COM 组件导入 .NET 的过程称为“.NET 与 COM 互操作”。

历史

  • 2008 年 1 月 13 日:首次发布
© . All rights reserved.