Dr. GUI .NET 1.1 #0 - 介绍 .NET、Hello World 并大体了解 .NET 运行时的内部机制

发布日期: 6/15/2004 | 更新日期: 6/15/2004

针对 Microsoft .NET 框架版本 1.1 进行了修订

摘要:在解释为什么对程序员来说 .NET 框架很有趣之后,Dr. GUI 介绍了 .NET 框架、Visual Basic .NET 和 C#。然后,好博士用 Visual Basic .NET、C# 和 ASP.NET 演示了“Hello World!”程序,并说明了如何在 .NET 框架中编写交换函数。最后,Dr. GUI 展示了几个程序的 IL 和元数据,让您看见框架的外表下面藏着什么。

*

内容

本页内容
Dr. GUI .NET 回来了……Dr. GUI .NET 回来了……
什么是 .NET?什么是 .NET?
.NET 框架中 Dr. GUI 的魅力.NET 框架中 Dr. GUI 的魅力
为什么要学习 .NET 框架?为什么要学习 .NET 框架?
我们将讨论什么?我们将讨论什么?
安装注意事项安装注意事项
为 .NET 编程为 .NET 编程
用 C# 和 Visual Basic .NET 编写 Hello World .NET用 C# 和 Visual Basic .NET 编写 Hello World .NET
使用 ASP.NET 交换变量使用 ASP.NET 交换变量
试一试!试一试!
加入我们!加入我们!
在哪里进一步学习在哪里进一步学习
本期主题和下期主题本期主题和下期主题

查看与本文一同提供的清单文件的源代码

Dr. GUI .NET 回来了……

Dr. GUI 的教程系列的定期读者可能已经发现好博士好久没有来了,这是因为他最近在休假。现在他回来了,Dr. GUI .NET 专栏将比过去办得更好。

在各种更新之后,Dr. GUI 目前正在修订文章,好让它们符合 Microsoft? .NET 框架 和 Microsoft Visual Studio? .NET 2003 的最终发布版本 1.1。修订后的系列文章在客户端应用程序中使用 C# 和 Microsoft?Visual Basic?.NET,并在 Microsoft?ASP.NET 应用程序中使用 Visual Basic .NET。

所以,好博士又接受了相同的旧使命,但现在使命经过更新了。这是为了帮助您了解 .NET 框架及了解如何使用它对您最有利,不管您现在进行的是什么种类的编程。

为什么应当阅读 Dr. GUI .NET?

在继续阅读后面的内容之前,有必要了解一下本专栏将讨论什么内容、谁有可能从中受益以及如何阅读本专栏。

简单地说:Dr. GUI .NET 向您介绍如何为 .NET 框架编程。无论您选择使用 C# 还是 Visual Basic .NET,您都会找到针对该语言的文章和用该语言编写的代码。(如果您使用 Microsoft JScript?.NET 或 C++,Dr. GUI 就只好提前向您道歉。时间有限,无法全面涉及。)

所以,如果您是 C、C++、C# 或 Microsoft Visual J++? 程序员(或者您使用的是名称以“J”开头的语言,这类语言从现在起称为“Brand J”),那么您将希望使用 C# 了解 .NET 框架。请继续阅读。如果您是 Visual Basic 程序员,则正好可以在这里获得您需要的内容。

由于示例使用了几种语言,因此每个人都将了解一点其他语言。这是好事,关于语言的争论从来就没有停止过,所以很多代码将同时用几种语言编写。(Dr. GUI 猜测通晓两种语言或多种语言可能会得到加薪。)

但请等一下,还有其他事情!除了控制台应用程序以外,我们还将把所有示例编写成 ASP.NET 应用程序。它们并不是高水平的 ASP.NET 应用程序,而您也不用在这里学习如何成为一个好的 ASP.NET 程序员(有关这类信息,请参阅 http://asp.net/)。但如果您是 ASP 或 ASP.NET 程序员,您将能够看到 .NET 框架的丰富性可以使您的编程工作变得更容易并且效率更高,结果,您将成为一个更好的程序员。

如果您不是 ASP.NET 程序员,您将有机会了解一点有关 ASP.NET 编程的事情,这也许会激发您在其他地方学习更多这方面的内容,并使用 ASP.NET 进行一些更高级的编程。为了编写本专栏,Dr. GUI 确实学习过 ASP.NET 编程,并的确从中得到了乐趣,他希望以后有更多了解,这是因为对于目前没有 Web 编程经验的人来说,ASP.NET 确实使 Web 编程变得很容易。ASP.NET 使 Web 编程容易和有趣,因为它通俗易用。

为了简便起见,在本专栏之后,我们编写的大多数 ASP.NET 应用程序将采用 Visual Basic .NET。Dr. GUI 再次向喜欢使用 C# 的人提前道歉,但请注意,将 C# 控制台示例转换成 ASP.NET 是非常容易的事情,尤其是因为每次都会有 Visual Basic .NET 控制台应用程序和 Visual Basic .NET 及 ASP.NET 示例作为指南。(查看与本文一同提供的清单文件源代码。)

谁应当阅读 Dr. GUI .NET?

谁应当阅读 Dr. GUI .NET?他们是希望为 .NET 平台编程的任何人,包括 C#、C、C++、Visual J++、Brand J 和 Visual Basic 程序员,以及无论使用任何语言为 ASP 和 ASP.NET 编程的人。您将了解到什么?您将略微了解 .NET 框架的形成过程和它的工作原理,并了解很多如何用它编写有效程序(不管编写的是什么种类的应用程序)的内容。

尽管没有针对每个人讨论所有方面

Dr. GUI .NET 无法针对每个人讨论所有方面。如果您想了解某些内容,如,高级 ASP.NET 应用程序开发和数据库访问技术,本文将不适合您。幸运的是,有很多很好的信息源,而最好的入门信息源之一是 http://asp.net/

为什么选择 Dr. GUI .NET?

那些一直在阅读“询问 Dr. GUI”和更旧的 Dr. GUI .NET 版本的人知道 Dr. GUI 非常热衷于 Microsoft .NET,即使他不能总是百分之百地确定在任何特定时间 .NET 将包括的所有内容是什么以及不包括什么。(如果希望查找这方面的内容,请阅读官方的 .NET Web 站点。)所有命名混淆让好博士想起 Microsoft ActiveX? 的故事,这就是哪里有营销操作,哪里就有命名混淆。Dr. GUI 喜欢“ActiveX”中“X”的意思被假定为沉默这个意见,尽管这没有坚持多久。.NET 世界中同样的事情是这个点(“.”)的前面是否要有个空格。规则(至少是 Dr. GUI 的理解)是:产品有,如 Visual Studio .NET;但技术没有,如 ASP.NET。(Dr. GUI 甚至不想知道这是为什么。)

不管好博士是否准确知道什么是 .NET 的一部分而什么不是,以及在随后的几年里这会有多少变化,但他确实了解对开发人员很重要的关键部分:.NET 框架。他不仅“了解”这部分内容,而且他对此非常热衷,它将使开发工作更有趣和更高效。随着 .NET 框架将在以后几年里不断提高,不久以后,它会是我们任何时候都不可缺少的东西。

获得 .NET

现在,您可以获得 .NET 框架 1.1,不管有没有 Visual Studio .NET。并且,如果您在编写 ASP.NET 应用程序,那么现在已经有了新的免费 IDE(称为“Web Matrix”)技术预览版可供您试用。

.NET 框架:免费!

.NET 框架本身(包括编译器)是免费的。可以在 .NET Framework Downloads 找到 .NET 框架 SDK 和可再分发文件。从这个 URL 还可以下载您(和您的客户)运行 .NET 框架应用程序所需的可再分发部分。这两项都是免费的。

Web Matrix:免费!

下面将讨论到,Visual Studio 是使用 .NET 框架也是使用C/C++ 中的常规本机代码来编写各种应用程序的好工具。

但是,如果您只编写 ASP.NET 应用程序,可能希望尝试 Web Matrix。Web Matrix 是用于构建 ASP.NET Web 应用程序的 IDE 的技术预览版(0.5 版),这个 IDE 受到专业人员的广泛支持。它没有 Intellisense 也没有调试器,并且没有安装它自己的、带索引的更快的帮助系统,而是依赖于 MSDN Online 作为帮助系统。所以 Visual Studio 仍然物有所值。另一方面,它的下载文件只有 1.2 MB,并且是免费的,那么为什么不试试它呢?可以在 http://asp.net/webmatrix 找到它。

Visual Studio:不免费,但物有所值!

尽管可以免费为 .NET 框架开发程序,但 Dr. GUI 热忱建议您购买 Visual Studio .NET Professional Edition(或更高版本),或者至少买一种单语言标准版本,如 Microsoft Visual C#?.NET。标准版的建议零售价为 109 美元,这真的非常便宜。

如果您是 MSDN 订户,应当在不久以后收到您的 Visual Studio .NET(如果您还没有收到的话)副本。也可以在 MSDN Subscriptions 下载它(非常大)。(订阅 MSDN 是获得 Visual Studio .NET 和开发 Microsoft? Windows? 程序所需的其余所有工具的一个最好方法。)如果您没有订阅 MSDN Professional、Enterprise 或 Universal,可以在您喜欢的软件零售商那里购买 Visual Studio .NET 或一个单语言标准版。相关事项,请参阅 Visual Studio .NET 站点。“Developer Tools”链接下面列出了各个单语言标准版。

如果您像 Dr. GUI 一样是习惯使用 C++/MFC 的人,您尤其会对 Visual Studio .NET 与 ASP.NET Web 窗体的组合使构建 Web 应用程序变得如此容易和有趣感到吃惊。过去,由于设置 Web 服务器的争论、请求/响应编程模型和编写 HTML 和脚本混合代码的复杂化,以及可用的编写脚本的语言存在的限制,Dr. GUI 已尝试不再编写 Web 应用程序。但是,Visual Studio .NET 可以自动在 Web 服务器中设置应用程序,而且控件/事件模型使 Web 窗体编程变得与编写 Visual Basic 代码一样容易(并且不需要编写 HTML,除非您想这么做),另外,由于用于所有 .NET 框架应用程序的编程语言是完全相同的语言,因此,您就有了功能强大的标准语言,该语言带有难以置信的丰富类库可供您任意使用。换句话说,Web 编程现在与编写 MFC 或 Visual Basic 应用程序一样有趣和容易。

如果您是 ASP 程序员,您将对编写 Web 窗体的容易程度以及编写能够在不同类型的浏览器上很好工作的 Web 页是如此简单感到吃惊。一旦了解了 .NET 框架,您将会感谢框架为您提供的难以置信的强大功能是如此易于使用。

但如果您使用 C/C++ 来编写本机代码的应用程序又如何呢?Visual Studio .NET 2003 有没有为您提供任何工具?当然有。只需对代码重新编译,您立即可以获得更紧凑、更快的代码。但 C++ 编译器遵守标准的程度还比以前强得多,这使您可以更容易与其他编译器双向移植代码,并且允许您使用此前无法使用的库。有关这方面的更多信息,请参阅 What's New in Visual C++ .NET 2003

我们将跳过如何使用 Visual Studio 和 Web Matrix 的讨论(只是本专栏),以便您自学 Visual Studio 和/或 Web Matrix 可以为您做什么,但我们随后将使用它们,因为这非常容易。

什么是 .NET?

我们刚才讨论过,要在任何一个时间点上准确地说出 .NET 是或不是什么都是很困难的。但如果您了解在 .NET 后面的某些关键的推动因素,就会更容易认识它是什么。

世界在过去是如何变化的

请考虑我们行业的某些趋势。很多人正在从使用孤立的 PC 转到使用通过 Internet(有线和无线、基带和宽带)同时连接到多个应用程序的 PC 和一大堆设备。他们开始期望无论到了哪里都可以在使用的任何设备上、以适合该设备的方式访问重要信息。由于可以通过 Internet 访问信息,他们会希望能够把来自多个信息源的原始数据合并成有意义的信息。最后,他们期望能够在安装和升级不会遇到麻烦的情况下使用软件,并且期望这会比 PC 过去的做法更可靠得多。

而这只是客户端计算机上的变迁。Internet 已经使基于服务器的应用程序变得比以前的任何时候更为流行,并且已经使无连接的请求/响应编程模型变得更常见。但是,服务器之间的通信(尤其是在运行于不同平台上的服务器之间)很困难,同样,处理各种浏览器以及浏览器各个版本之间的差异也很困难,更不用说处理所有不同类型的无线设备的困难了。由于大多数实际的 Internet 应用程序都是以数据库为中心的,因此,能够容易地访问各种各样的数据源就成为比过去更重要的事情。

.NET 如何帮助您

.NET 框架有助于使这些种类的问题更容易解决。例如,.NET 框架压缩版(用于设备)与 Visual Studio .NET 2003 一起交付,这样,您就可以在各种设备上(而不止是在 PC 上)利用 .NET 中优秀的公共语言运行库。

通过采用 Internet 标准,.NET 从一开始就是为了在 Internet 上很好地工作而设计的,这些标准包括支持 XML Web 服务,让程序可以使用 XML 很容易地从多个站点获得数据,并便于在不同计算机系统之间实现数据交换。.NET 还使访问数据变得更容易,并使您更容易编写能在各种各样的浏览器和设备上良好运行的 Web 应用程序,而不必针对每个浏览器和设备改写应用程序。最后,为了便于使用和提高可靠性,.NET 运行时还支持简化和可靠的安装和升级。这一点以及 .NET 运行时的安全性和版本控制功能还提高了可靠性,并使软件能够作为服务而不是产品进行销售。

使用 XML Web 服务把来自多个信息源的数据集成为可以使用的信息

另一个重要趋势是应用程序为了做某些有趣的事情而集成来自很多来源的信息。典型的示例是计划商务旅行:您需要买飞机票、租汽车和住旅馆。您希望买到这三方面都最符合您需要的服务,所以您需要从三类不同的公司那里取得数据。而且您的旅行还需要协调,以便您能按时到达,并在到达时有汽车和旅馆房间(当然,还要有宽带),而且可以及时返回。XML Web 服务使用 SOAP 和标准 XML 架构,它可以帮助各应用程序通过 Internet 以业界标准的方式通信,以便应用程序可以使用其他计算机的信息并与其他计算机共享信息,而不管其他计算机使用的是什么平台。而 .NET 框架差不多使编写和使用 Web 服务成为非常轻松的事情。但是,如果您想看到一个使用 .NET 实现的、大型和真实的 Web 服务的示例,请访问 http://terraserver.microsoft.NET/,这个示例提供了全世界的地图和航空照片信息(承蒙 Microsoft TerraService 项目的支持),还有其他信息,如美国人口普查数据。

最后,Microsoft 和其他公司将提供有趣的功能来作为 XML Web 服务,您可以像使用本地对象一样使用这些服务,当然还不止这些。假如您用可以承受的价格获得了需要的功能,那么使用 OPWS(他人的 Web 服务,这是 SEC 的变体,而 SEC 是他人的代码)总是好事情。

所以,.NET 框架将使您更容易编写新类型的应用程序,这样的应用程序比以前更容易安装并且更可靠。并且,这些应用程序将是功能强大的,因为它们将能够利用由 Microsoft 和其他人(可能就是您)提供的 XML Web 服务!

.NET 框架中 Dr. GUI 的魅力

Microsoft 操作系统 API 集合的简史

使用 .NET 框架编程不同于使用 Microsoft Win32?API 编程,正如 Windows 编程非常不同于 DOS 编程。这些 API 中的每一个都是它所处时代的产品:80 年代早期是 DOS,80 年代中期是 Windows 而 90 年代晚期是 .NET。

DOS

DOS API 在概念上要追溯到为小型计算机系统而设计的各种单任务操作系统。尽管当微型计算机第一次出现时小型计算机上流行的是诸如 UNIX 和 VMS 这样的操作系统,但微型计算机没有足够的内存或速度来运行这些相对复杂的操作系统。受到内存和速度的严重限制,诸如 DOS 这样的操作系统主要是用汇编语言编写的,这样它们的速度才能尽可能快,体积才能尽可能地小。DOS 的 API 主要是一组软件中断调用(还记得 INT 21h 吗?),您绝对需要汇编语言才能执行调用(也许是通过使用至少部分以汇编语言编写的运行时库),另外 DOS 还提供了少量的(几十个)服务,但它们大多数面向磁盘和字符模式 I/O。DOS 只支持单任务(因此只有一个执行线程),并且 DOS 程序一直控制着计算机系统,当它不做其他事情时,才通过循环轮询来检测键盘输入是否已做好准备。

Windows

Windows API 是在 80 年代早期设计的,那个时候里根是总统,C 是大多数系统程序员选择的语言。(某些重要的系统也用 Pascal 编写,在功能上,该语言非常类似于 C。)Stroustrup 的里程碑式著作 The C++ Programming Language 直到 1986 年才发布。“结构化编程”是那时的时髦,那时程序员学会了避开 goto,而面向对象编程 (OOP) 直到十年以后才成为主流。

结果,Win32 API 成为只有 C(或 Pascal)程序员才可能喜欢的 API。这时有命名空间但仅有一个,所有数百(随后是数千)个API 名称都很长,并且 API 作者提出了各种命名约定,来对它们进行分类。语言不直接支持抽象数据类型,所以程序员提出了各种命名方案,例如,Microsoft 的(由 Charles Simonyi 提出)匈牙利方案,这种方案用代表变量抽象类型的缩写作为标识符前缀(例如,“i”代表索引,或“c”代表计数,这二者都使用基本语言类型“int”)。

但是,Windows 中最重要的差异是,为了利用图形用户界面,必须完全重新构造程序。因为 Windows 支持多任务(尽管在 Win16 中不支持多线程),但当您的程序不做任何事情时它需要将控制权返回给操作系统。因此,您的程序没有一直保持控制权,而是被重新构造为一组消息处理程序,每个消息处理程序都快速响应来自操作系统的消息(如,鼠标单击、按键或菜单选择),并尽可能快地返回给操作系统,以便让您的应用程序可以等待下一个消息。作为对重新构造您的应用程序的交换,您可以利用丰富的 Windows 功能,如设备独立性、对动态链接库和多任务的支持以及功能强大的标准化用户界面功能,如窗口、对话框、控件(如,按钮、列表框和编辑控件)和菜单。

面向对象编程

在 90 年代早期,面向对象编程变得流行起来。使用面向对象编程,就有可能编写出更大的项目,这样的项目可以在程序对象之间定义更好的交互,并且未定义的交互更少。对象允许程序员以强大的方式创建抽象,这使编程上升到比以前更高的级别。

Visual Basic? 在它的运行时环境中封装了很多消息传送逻辑,并通过允许 Visual Basic 程序员集中编写消息处理函数,使程序员能够以基于对象的方式进行 Windows 编程。随着 C++ 变得流行起来,类库(如 MFC)允许程序员将其 Windows 应用程序编写为交互对象组,这些对象组带有由应用程序框架提供的很多默认交互。

但在 Visual Basic 和 MFC 程序下面的 API 仍然是在面向对象编程流行起来之前所设计的旧 Windows API。(公平地说,应当注意到事实上 Windows 确实体现了某些面向对象概念。)但是,Visual Basic 和 MFC 运行时库的大小证明了这样的事实:它花了越来越多的努力来填充面向对象编程与旧的、单调的 API 集合之间的空隙。

组件

90 年代中期,新的概念流行起来:软件可以用可互换组件构造,这很像一个人可以用一套部件组装出一个音频系统或家庭影院。思路是,通过小心定义接口并按照良好定义的协定来实现它们,就可以按相对容易的方式混合和匹配软件组件。

支持基于组件的编程要求向单调的 API 集合(即在 Windows、OLE 和 COM 中)添加很多东西。这些添加中的某一些非常复杂,因为基于 C 的 API 的本意从来不是要支持诸如动态创建软件对象和自动进行对象生存期管理这类操作,更不要说 C 和 C++ 的预期用途是为了编写整体式的应用程序,而不是由一组组件组成的应用程序。

结果,编写组件成为乏味的事情,并且需要文件和转换器来弥补这样的事实:这些语言并不真正支持基于组件的编程。虽然 Visual Basic 和诸如 ATL 这样的库减轻了某些单调,但很多高级(但有趣)的操作仍然实现得很艰苦。而且,由于 Windows 缺少对灵活的版本控制策略的支持,新的组件版本通常会导致现有应用程序无法正常运行。

功能多但可通用的少

最后,各种 API 年复一年添加到 Windows 中的这一事实在编程模型中产生巨大的不一致性。即使原始 Windows API 也有某些糟糕的不一致性 — 看一看与设备上下文、笔、字体和笔刷相比,窗口、菜单和控件的处理方式是如何不同就知道了。但更严重的问题是 Windows 中对错误的不同处理方式可能有半打之多。(也许更多。Dr. GUI 没有清点过。)字符串类型有可能有半打之多。而这只是冰山一角。

很明显,在 API 编程模型的大杂烩和为基于组件的程序和 Internet 编程提供良好支持的需要之间,升级到新的、干净设计的、一致和现代的 API 的时机已经成熟。Microsoft 对这些问题的回答是 .NET 框架。

保持连贯性的全新开端:.NET 运行时

正如 80 年代晚期是与旧的 DOS 编程方法决裂的时候一样(那时人们常问:什么?放弃 TSR?),现在是 Windows 程序员开始与单调、旧式的 Windows API 决裂,转而支持现代、面向对象、基于组件的 API 的时候了。Dr. GUI 建议您使用 .NET 框架和运行时,以便可以享受现代运行时的好处。

彻底地基于组件

要理解 .NET 运行时,必须理解这一点:.NET 运行时是为了为现代的基于组件编程提供最好的支持而设计的,这种支持是在运行时环境中直接提供的。换句话说,它是完全针对组件的。如果理解这一点,就很容易理解为什么 .NET 运行时被设计成这个样子。

正如 Windows 添加了对窗口、控件、绘图和菜单的直接支持,并为支持设备独立性而向基于消息的编程和抽象提供了基础结构一样,.NET 运行时直接支持组件(包括属性和事件)、对象、继承、多态性和接口。

多语言、与旧代码互操作!

并且,无论是运行在您的计算机还是在其他计算机上,它提供该支持的同时还允许您使用 20 多种不同的编程语言中的任何一种,而且仍然能与非 .NET 代码交互。换句话说,.NET 代表了全新、现代的开端,而又保持了连贯性:您可以使用从熟悉到陌生的各种各样语言,并继续使用旧的组件和 DLL 而不需要对它们加以修改。甚至可以像使用任何 COM 对象一样使用 .NET 组件,这样,您的新 .NET 代码就可以与旧 COM 应用程序一起工作。(您可能希望将该语言的灵活性和与旧代码的互操作容易性与市场上其他运行时系统,尤其是 Brand J,进行比较。)

新功能支持组件

.NET 运行时中还设计了其他有趣的主要功能以便为组件开发提供最好的支持。对属性和事件的直接支持使基于组件的编程在不需要特殊的接口和适配器设计模式的情况下变得很容易。自动内存管理允许您分配对象并在组件之间传递它们,而不必担心当不再需要组件时应当由哪个组件负责释放该对象,从而解决了麻烦的对象生存期问题。对序列化的支持可以按各种格式,包括业界标准的、基于 XML 的 SOAP(而不只是专用的二进制格式),来启用“冷冻-干燥”组件并随后重新组建它们。由于能够调用和创建业界标准的 XML Web 服务,您就可以向在 Internet 上任何地方使用任何设备的任何人公开组件,并使用来自 Internet 上任何地方的任何设备的组件。异常处理机制则提供了健壮、一致的错误情形处理方式。每个代码模块都有内置的完整元数据的这一事实,意味着像动态创建和方法调用这样的功能变得很容易,并且是类型安全的。(而且,.NET 框架甚至允许即时创建和执行代码!)并且您可以控制应用程序使用组件的哪个版本,从而使您的应用程序更可靠。最后,由于代码采用了与处理器无关的和容易验证的中间语言 (IL),而不是某些特定的机器语言,这就意味着您的组件不仅可以运行在各种计算机上,而且您可以肯定您的组件不会覆盖它们不拥有的内存,也就不可能因此而造成故障。

这些关键功能中的每一个都存在于 .NET 运行时中,以便编写健壮的面向对象组件变得很容易。

等一等……还有更多!

除了 .NET 运行时所提供的所有良好的组件支持功能以外,.NET 框架还包括数量巨大的类,这些类是为了提供基础结构以解决目前的编程问题而设计的,这些问题包括使用 ASP.NET 时所涉及的复杂的、基于组件的 Web 服务器应用程序支持(和对充当客户端的各种浏览器和移动设备的支持)、XML 支持、增强的数据库访问和其他很多问题。

.NET 框架的一部分将以 .NET 框架压缩版的形式供各种设备使用,所以,学习用于 PC 和服务器的 .NET 框架将对您为设备编程有所帮助。

标准化……

最后,作为 .NET 运行时的一个主要部分,公共语言基础结构 (CLI) 已经与 C# 语言和 IL 格式一起由欧洲计算机制造商协会 (ECMA) 和 ISO(国际标准化组织)实现了标准化,ECMA 还完成了对 JavaScript 和 JScript 的标准化 (http://www.ecma-international.org/publications/standards/ECMA-262.HTM)。这就让其他组织有机会在其他平台上完成与 .NET 兼容的实现。有关详细信息,请参阅 ECMA and ISO/IEC C# and Common Language Infrastructure Standards

还值得一提的是 Ximian,这是一家开放源代码软件公司,它赞助的一项开放源代码项目称为 Mono (http://www.go-mono.com/),该项目致力于构建一个 .NET 框架的开放源代码版本。有兴趣的话,可以查找 Dare Obasanjo 对 Mono 项目的组长 Miguel de Icaza 的访谈

使用功能强大的 Visual Studio .NET 工具为 .NET 框架编程

.NET 框架不仅很精彩,而且当您使用 Visual Studio .NET 开发应用程序时,还会获得功能非常强大的开发环境,该环境把您需要的所有东西方便地提供给您。文档直接集成到 Visual Studio .NET 集成开发环境 (IDE) 中,包括动态帮助,它可以观察您键入和单击的内容,并猜测什么帮助主题与您做的事相关。如果猜测是正确的(通常都是),单击一下,您需要的帮助就会立刻显示。

Microsoft IntelliSense? 帮助您正确键入语句、变量名和成员名,甚至向您显示您调用的方法的参数名称。(该功能可以用于您编写的类,也用于库中的类。)这使编辑源代码变得更容易、更快、错误机会更少。

还有其他很多好功能,总之,Visual Studio.NET 确实是令人非常愉快的编程工具,并且它非常有效率!

为什么要学习 .NET 框架?

如果您已经为另一个平台(如,Windows、Linux 或 Java)编程,您可能想知道,为什么您需要再来学习这个新平台:NET 框架。

Dr. GUI 以这种方式看待这件事:由于 .NET 框架平台允许程序员非常高效率地工作(在所提到的平台中,它可能是最有效率的),因此不了解它是愚蠢的。它不是适合所有项目的最佳平台(没有这样的平台),但好博士认为您将发现它是很多项目的最佳平台。因为它可以与其他平台很好地互操作,所以,您可能希望项目的某些适合 .NET 框架的部分在 .NET 框架中完成,然后对于项目的其余部分,可与本机代码、COM 对象或者其他计算机系统进行互操作。

对于某些种类的应用程序来说,.NET 框架是明显的最佳选择。使用 ASP.NET,Web 应用程序确实很容易编写并且功能强大。有了 .NET 框架,XML Web 服务也确实很容易编写。

如果您需要在项目中使用 .NET 框架而承诺要学习它,请继续阅读下去,Dr. GUI 将帮助您。但如果您不肯定,也请继续阅读。只需用相对很短的时间,Dr. GUI 就将帮助您很好地理解您很可能希望使用的平台。(即使您不使用它,了解它也有助于您进行其他编程,正如学习外语可以帮助您更好地理解自己的母语。)

Dr.GUI 的处方:每周仅用一个小时练习 .NET……

……获得高强的编程技能

因为 .NET 相对较新,Dr. GUI 建议您为了超越学习曲线应当:每周只要找出一个小时来学习 .NET。

这些教程文章将每月发布两次,它们提供了练习机会,可以使您通过完成这些练习来实际了解正在阅读什么内容。所以,假定用一小时阅读文章(Dr. GUI 承诺,随后的文章将更短,并且阅读时间可能更少)并用一小时或两小时做练习,您应当能够用相对少的努力了解到某些很好的新技术,这样,平均时间是每周约一小时。

如果您每周投入一小时,您将获得 .NET 框架的牢固知识。您将了解它如何工作,并能愉快地为 .NET 平台编程。

与一个朋友(或两个、或更多……)一起学习

正如有一个测验伙伴可以帮助您学习技术(这也是您的义务),每次和朋友或同事一起学习 Dr. GUI .NET 将帮助您更好地学习,并且会有更多乐趣。或者,更好的方法是,将一组学员组织在一起。也许您希望有一个讨论组。也许完成每组练习或者遇到困难和问题时,大家都应当相互发送电子邮件。

参加 GotDotNet 上的 Dr. GUI .NET 论坛

GotDotNet 上还为与本专栏相关的内容设立了新论坛:http://gotdotnet.com/community/messageboard/MessageBoard.aspx?id=46

好博士无法在论坛上回答您的 .NET 框架编程问题,但他将回答有关这些专栏的问题。

用免费资料入门

不要忘记您可以从 MSDN 获得 .NET 框架 SDK,其中包括您将需要的编译器,甚至还有调试器,它们是免费的。这是开始学习的好方法。虽然 Dr. GUI 非常肯定您不久将希望购买 Visual Studio .NET 的一个副本,以便得到很好的 IDE、帮助系统和调试器,更不用说 IntelliSense 功能了。

我们将讨论什么?

面对巨大的 .NET 框架,您可能想知道我们将讨论什么和什么时候讨论?

我们将以非常基础的知识为起点开始本专栏的讨论。您已经阅读到 .NET 框架是为了解决什么问题而设计的。随后,我们将讨论 .NET 运行时的各个方面,包括不可缺少的“Hello World”程序,并介绍元数据和中间语言 (IL)(这是 .NET 的机器语言)。

下一次,我们将开始讨论 .NET 框架的基础知识,包括所有类的母类 System.Object。我们还将讨论垃圾回收和一点有关接口的知识。

在这之后,我们将用几篇文章介绍 .NET 框架和运行时的基础:数据类型、异常、文件和网络 I/O、序列化、线程处理和定时器以及调试。

然后,我们将讨论与 Windows 程序员最密切的东西:图形用户界面类。(这可能不会是 ASP.NET 程序员有兴趣的内容。)

.NET 框架为数据库访问、XML 和 Web 应用程序提供了很多好功能,但好博士目前正在计划让其他人来介绍这些问题。

每期专栏都有示例程序、示例的解释和您可以尝试的练习。这些示例都是用 C# 和 Visual Basic .NET(包括带有 Visual Basic .NET 的 ASP.NET 版本)编写的,它们将重点阐明更大的概念,以便您更好地理解 .NET 背后的设计哲学。

为什么要使用 C# 和 Visual Basic .NET?

如果 .NET 支持 20 种左右的语言,那么为什么 Dr. GUI 的所有 .NET 专栏只使用 C# 和 Visual Basic .NET 呢?一开始,Dr. GUI .NET 专栏的测试版本只使用 C#。当好博士开始办这个专栏时,C# 成为必然的选择。原因是:.NET 框架的大部分是用 C# 编写的,所以大多数早期的示例也采用 C#。这似乎是那时必然的选择。(不要忘记 Dr. GUI 也是一个熟悉 C++ 的人。)

但现在,Visual Basic .NET 几乎有和 C# 一样强大的功能(它们各自还有自己独有的功能),所以,对于 .NET 编程来说它是同样好的选择,而现在很明显的是,Dr. GUI .NET 应当同时使用这两种语言。因而,好博士(在 Coding4Fun 的作者 Duncan Mackenzie 的帮助下,感谢 Duncan!)已经在专栏中同时提供 C# 和 Visual Basic .NET 示例。

但请等一等,还有其他说明!为了使这些专栏与 ASP 和 ASP.NET 程序员相关,Dr. GUI 还使用 Visual Basic .NET 包括了采用 ASP.NET 编写的示例。从这些专栏您学不到如何成为一个好的 ASP.NET 程序员的知识(很多更好的地方提供这类知识,如 http://asp.net/),但您将学习如何在您的 ASP.NET 程序中充分和有技巧地利用 .NET 框架的全部功能,从而使您在更好地了解工具的情况下成为更好的程序员。并且,如果您现在不是 ASP.NET 程序员,您将初步认识到 ASP.NET 的易用性和强大功能。

虽然您可以在 .NET 中用很多语言编程,但 C# 和 Visual Basic .NET 是专门为很好地使用 .NET 而设计的,并且它们被专门设计为支持基于组件的编程。它们都是编程的好语言,尤其是使用Visual Studio 时更是如此。它们很容易使用,但没有 Brand J 的恼人的问题。例如,您可以用 C# 和 Visual Basic .NET 实际编写 swap 函数,我们随后会在本专栏中介绍这一点。(Brand J 无法做到这点是 Dr. GUI 对该语言经常抱怨的问题之一。)

Dr. GUI 认为 C# 和 Visual Basic .NET 将有可能成为 .NET 框架编程的最流行语言。应当使用哪个呢?任何一个都不错。此外,通过使用 C# 和 Visual Basic .NET,您将有机会开始学习这两种语言和 .NET。如果选择使用另一种语言,看见采用这些语言的示例也不会妨碍您;您对 .NET 框架和运行时的了解将适用于您所使用的任何语言。

如果喜欢使用其他某种语言,将代码转换成您选择的语言将是相对简单的过程。但 Dr. GUI 只有一个人,他没有时间这样做。如果您希望承担这项工作,可以将您的转换代码放在为讨论这些专栏而已建立的新闻组中。(本文后面将详细介绍此内容。)

现在我使用 Visual Basic,为什么要使用 Visual Basic .NET 而不使用 C#?

Dr. GUI 已听说很多 Microsoft Visual Basic 程序员在迁移到 .NET 时正在考虑切换到 Visual Basic .NET 以外的其他语言,如 C#。好博士想请他们在这样做之前重新考虑。

他听说的理由类似这样:“既然 Visual Basic 改变了很多,我最好学习一种新的、功能更强大的语言”。

如果其他语言的确比 Visual Basic .NET 功能更强大,这也许是对的。但 Visual Basic .NET 与 .NET 框架的关系并不像 Visual Basic 与 Windows 的关系。通常,.NET 的各种语言都处于同一运动水平,并且或多或少具有同等强大的功能。差异很小。

回忆一下,Visual Basic for Windows 需要沉重的运行时库才能与 Windows 接口。结果,Visual Basic 编程在很多方式上与用 C 或 C++ 的 Windows 编程非常不同。通常这是好事,因为 Windows 非常复杂,而 Visual Basic 编程则容易得多。问题是 Visual Basic for Windows 受到或多或少的限制,编程人员只能做运行时库设计人员在设计运行时库时想得到的事情。如果希望做他们没有计划好的事情,就将非常困难,有时几乎是不可能。(使用计算机,没有什么是不可能的。)

另一方面,Visual Basic .NET正如其他每种 .NET 语言一样,直接与 .NET 框架对话。(存在一个小型的 Visual Basic .NET 运行时,可以提供某些不在 .NET 框架中的、Visual Basic 特有的功能。但它与旧的运行时完全不一样。)

换句话说,Visual Basic .NET 第一次提供了基础平台的全部功能。Visual Basic .NET 几乎可以做 C# 能做的任何事情。现在,它们有一些语言特性上的差异,这是因为每种语言都有一小部分其他语言没有的特性。但这些差异非常小。

例如,因为 Visual Basic .NET 直接支持晚期绑定,所以用 Visual Basic .NET 实现此功能要比用其他语言要容易得多。而且,Visual Basic .NET 能够自动将事件与正确命名的事件处理方法相联系,从而节省了在其他语言中必需的某些代码。

另一方面,C# 允许编写可用类似于 C 和 C++ 的方式操纵指针的“不安全”托管代码(更准确地说,这是无法验证为类型安全的代码)。并且使用 C++ 托管扩展的 C++ 允许执行类似混合托管和非托管代码这样的操作。但需要非常具体的性能原因您才会这样做,而不会是每天的编程需要。

但您不必挑选一种万能的语言:使用 .NET 框架提供的非常好的混合语言功能,您可以用 C++ 或 C# 只编写需要这些语言的程序部分,然后用您选择的语言做其余工作。

这里的关键是:如果您已经是 Visual Basic 程序员,则没有必要只是为了利用 .NET 框架而学习一种全新的语言。您可以了解 Visual Basic 6.0 和Visual Basic .NET 之间的差异,并重点了解 .NET 框架,包括继承和异常。您将能够做一个 C# 程序员可以做的所有事情。并且,如果您决定随后再学习 C#,那么您使用 Visual Basic .NET 所学到的几乎任何事情 都将直接转移到 C#。(Dr. GUI 猜测了解 Visual Basic .NET 和 C# 的程序员将比那些只了解其中一种语言的人有更高的工资,所以,正如在真实生活中一样,双语就是优势。)

所以,Dr. GUI 的建议是:

如果现在主要采用 Visual Basic 编程,请学习 Visual Basic .NET 和 .NET 框架。如果需要,可以随后空闲时学习 C#。在 Visual Basic .NET 中学到的几乎所有东西都适用于 C#。

如果主要用 C、C++ 或 Brand J 编程,请学习 C# 和 .NET 框架。(还可以继续使用 C++ 或 J#,如果您喜欢。)如果希望提高工资,请随后学习其他语言,如,Visual Basic .NET。

如果需要与很多非托管 C/C++ 代码互操作,或需要利用每一点性能,请对确实需要快速运行的代码使用 C++ 托管扩展,并对其余代码使用 C#。

如果主要用 Microsoft Jscript? 或 JavaScript 编程,请学习 Jscript .NET 和 .NET 框架,如果愿意可以延伸到其他语言。

如果您在管理项目,请选取最符合您的团队需要的语言。并自由使用另一种语言来解决必需使用该语言才能解决的那部分问题。

换句话说,使用什么语言确实是没有关系的。在 .NET 框架中您可以使用任何语言做任何事情。当然,不同的语言特性将使某些任务用某些语言比用其他语言更容易。例如,前面提到过,Visual Basic .NET 提供自动晚期绑定,但如果用 C# 则需要编写几行代码才能使晚期绑定发生。这就是为什么能够很容易地混合各种语言很吸引人的原因!

因此,一开始使用您最喜欢的语言,然后在您有时间和愿意时再采用其他语言。

或者,如果您喜欢,再学习新的语言。这完全由您决定。只需知道,您不必仅仅是为了利用 .NET 框架的全部功能而学习新的语言。

安装注意事项

大多数安装都非常简单,只需单击适当的安装程序或 URL,然后就能完成操作。安装程序既容易理解也很有效。(如果希望使用 ASP.NET,一定要在安装之前启用 Microsoft?Internet 信息服务 [IIS]。)

有一个小技巧,虽然:正在安装 .NET 框架 SDK 时,系统可能会问您是否要注册环境变量以便可以从命令行编译。您希望这样做,以便能够从命令行使用工具。请确保选中复选框,以便注册环境变量,并且能够使用命令行工具。

如果安装 Visual Studio .NET,将没有机会选中该复选框。您应当使用 Visual Studio .NET 2003 Command Prompt 快捷方式启动命令提示符,该快捷方式位于 Microsoft Visual Studio .NET 2003/Visual Studio .NET Tools 下面的 Start 菜单上。使用该快捷方式进入命令提示符环境就能设置正确路径。

另外,在安装期间,请确保没有启动任何程序,如,Microsoft? Internet Explorer 或 Microsoft Outlook?。Dr. GUI 没有这样做,结果不得不修复安装。请等到 Visual Studio .NET 2003 安装完成,再接收电子邮件。

为 .NET 编程

Visual Studio .NET 被设计成使 .NET 编程比其他方式更容易,诸如自动语句完成和拖放窗体编辑等功能使得使用不熟悉的 API 集合更容易。它将帮助系统集成到 IDE 中,这确实带来了巨大好处。

未来,我们将使用 Visual Studio .NET,但在本专栏中,好博士仍然希望您用老办法编程,即使您已经有了 Visual Studio .NET:使用记事本(或其他某个编辑器,如 Visual Studio,如果您喜欢)编写源文件,并保存到磁盘,然后从命令行编译并运行。(对于 ASP.NET 应用程序来说,请将代码复制到适当的 Web 应用程序目录中,并使用 Internet Explorer 查看该页面。)这样做只需要 .NET SDK,而不需要 Visual Studio .NET。使用命令行工具还会让我们有机会看到产生了什么文件,并且看到后台发生了什么。

如何拼写?

在 .NET 程序中,大写和小写的使用约定可能不同于您使用的其他语言。但是,.NET 的规则很简单:除了参数名称和私有字段名称以外,所有标识符的每个单词的第一个字母要大写,包括第一个单词。该规则称为“Pascal 大小写规则”,来自于 Pascal 程序员之间的公共约定。

参数名称和私有字段名称的每个单词的第一个字母要大写,但第一个单词除外。(Microsoft 建议所有字段都是私有的;但是,可以使用保护的或公共的属性公开它们。)这称为“骆驼大小写规则”。Dr. GUI 不太肯定为什么这么叫。

您确实需要知道这些规则,因为 .NET 框架名称遵守这些规则,而且某些语言(如 C#)是区分大小写的。

所以,主输出函数的名称是 System.Console.WriteLine,它完全符合该首字母大写规则。System.Console.WriteLine 的格式字符串参数的名称可能是 formatString,而不是 FormatString。但是,字符串长度属性的名称可能是 StrLen,而不是 strLen

对于 Dr. GUI 来说,最难的事情是要记住使用 Main,而不是 main

用 C# 和 Visual Basic .NET 编写 Hello World .NET

不再啰嗦了,下面就是用 C# for .NET 所编写的可能是最简单的“Hello World”:

C#
// Compile with: csc hellocs.cs
class MyApp {
   public static void Main() {
      System.Console.WriteLine("Hello, world! (from C#)");
   }
}

下面是 Visual Basic .NET 中的代码实现:

Visual Basic .NET
' Compile with: vbc hellovb.vb
Class MyApp
   Public Shared Sub Main()
      System.Console.WriteLine("Hello, world! " + _
         "(from Visual Basic .NET)")
   End Sub
End Class
运行程序

要运行这些程序,只需创建(或从新闻组获得)包含这些代码的文本文件,然后使用代码中显示的命令行编译该文件。(如果需要设置路径以便编译器正常工作,请在框架 SDK 的 /bin 目录 [在 Dr. GUI 的机器上是:C:/Program Files/Microsoft Visual Studio .NET 2003/SDK/v1.1/Bin] 中运行 sdkvars.bat。)

然后,键入程序的名称运行该程序。例如,创建完文件,即可键入下面的某一个程序名称:

   rem C#
   csc hellocs.cs
   hellocs

   rem VB .NET
   vbc hellovb.vb
   hellovb
所有东西都在类中

您很可能注意到的第一件事情是 Main 函数是一个类的成员。

在 .NET 中,所有方法都必须是类或结构的成员。(下一次,我们将详细讨论结构。)这是因为,在 .NET 中基本的组织单位就是类型(类型除了指其他概念,还指类或结构)。Visual C++ .NET 的托管 C++ 扩展允许编写表面上存在于类的外部的变量和函数,但即使是这些变量和函数也存在于如下的类中:一个隐含的全局类。

看看吧!没有头文件!

不仅所有内容都在类中,而且类声明也是完整的。除源文件外,没有头文件、IDL 文件或任何其他文件。描述类时所需的所有东西都与类在一起。

那么,如果使用另一个不在源文件中的类,会发生什么?编译器怎样知道这个类中有什么东西?

回答是,编译器会读取程序集的元数据,而该程序集包含了您使用的类。刚才显示的程序隐式使用了 System.Object(因为所有类都是从 System.Object 派生的)。编译器自动转到 mscorlib.dll 程序集以获得该程序集的元数据,所以,它可以获得适于 System.Object 需要的类型信息。如果您使用来自不同程序集中的类,则需要在编译器命令行上使用 /r 选项来指定程序集,如:

   rem C#
   csc /r:foo.dll hellocs.cs

   rem VB .NET
   vbc /r:foo.dll hellovb.vb

顺便说一句,module(与 Visual Basic .NET 中的 Module 概念不同!)是可执行文件:可以是应用程序,也可以是库。它的扩展名通常是 .exe 或 .dll。assembly 是一个或多个 module 组成的集合。程序集中的一个文件包含了程序集的清单,清单是程序集中所含文件的列表。assembly 是可执行代码的最小单位,assembly 可以被部署和进行版本控制。(您将注意到,随后,当我们查看 assembly 的清单时,只有 assembly 有版本号。)

特殊的 Main

其次您很可能注意到 Main 的修饰符:publicstatic(Visual Basic .NET 中是 Shared)。在这些语言中,成员的默认访问控制权是 private;因而我们需要声明 Main public 才能让它被运行时调用。

我们将 Main 声明为 static(在 Visual Basic .NET 中是 Shared),这表示它是一个类方法,而不是实例方法。这意味着运行时可以调用它,而不用关心创建 MyApp 对象并将对该对象的 this 引用(在 Visual Basic .NET 中是 Me)传递给 Main 的事情。(注意,如果我们在 Visual Basic .NET 中使用 Module,则方法会默认为 PublicShared。)

注意,可以将类命名为任何名称;在这里,我碰巧将它命名为 MyApp。该版本的 Main 没有参数并且没有返回值,这是由 void 的返回类型来表示的。在 Visual Basic .NET 中,Main 是一个 Sub,而不是返回值为 void 的函数。

可以编写 Main 以携带包含命令行参数的 String 数组,并/或返回整数成功代码。

最后,我们调用 WriteLine 方法来编写该字符串。我选择使用函数 System.Console.WriteLine 的完全限定名称。在 System 命名空间中,WriteLineConsole 类的一个 static 方法(像 Main 一样)。

保存某些键入内容

经常键入完全限定类名称是很麻烦的,所以 C# 和 Visual Basic .NET 允许使用 using(或 Imports)语句来指定要使用的命名空间。例如:

C#
// Compile with: csc hellocs2.cs
using System;
class MyApp {
   public static void Main() {
      Console.WriteLine("Hello, world! (2) (from C#)");
   }
}
Visual Basic .NET
' Compile with: vbc hellovb2.vb
Imports System
Module MyApp ' VB-only change
    Sub Main()
        Console.WriteLine("Hello world! (2) (from VB .NET)")
    End Sub
End Module

因为编译器会搜索 System 命名空间和 local 命名空间,所以在调用 Console.WriteLine 时不必指定 System。这在此处的好处不大,但如果有很多对象引用和方法调用,则会非常方便,您将在后面的程序中看到这一点。

注意,命名空间 (System) 和您将在其中找到类 Console 的程序集是两个完全不同的东西。一个给定的程序集可以包含来自多个命名空间的类;同样,在给定命名空间中的类可以分散到多个程序集中。一个类逻辑上属于其一部分的命名空间与可以在其中找到该类的二进制代码的程序集之间没有任何关系。使用 /r 选项可以告诉编译器从哪里查找该类的二进制代码。使用 usingImports 语句,可以告诉编译器要使用什么命名空间。

仅 Visual Basic:Module 与类

在 Visual Basic .NET 版本中我们进行了另一个更改:我们没有让 MyApp 成为常规类,而是使它成为特殊类型的类,称为 ModuleModule 是 C# 中静态类所扮演的角色(如果 C# 有这样的角色)。大体上,所有方法都是共享的(在 C# 中是静态的)和公共的;因此,我们不必将 Main 声明为 SharedPublic。但注意,不能像对类一样创建 Module 的实例。

等一等!先不要离开!

在某些情况下(例如,如果从文件资源管理器运行 Hello 程序),则命令窗口有可能在您看到输出之前消失。要避免这样,请通过调用 ConsoleReadLine 方法,从键盘读取输入(这会使程序暂停,直到您按 Enter)。(对于控制台应用程序,我们将总是在 Main 中将该调用作为最后的语句。)这样,我们的程序最后看起来是这样的(我们已经回到 Visual Basic .NET 中的类):

C#
// Compile with: csc hellocspause.cs
using System;
class MyApp {
   public static void Main() {
      Console.WriteLine("Hello, world! (pause) (from C#)");
      Console.ReadLine();   // wait until Enter; last line
   }
}
Visual Basic .NET
' Compile with: vbc hellovbpause.vb
Imports System
Public Class MyApp
    Public Shared Sub Main()
        Console.WriteLine("Hello world! (pause) (from VB .NET)")
        Console.ReadLine() 'Wait until Enter; last line
    End Sub
End Class

ASP.NET 中的 Hello World(用 Visual Basic .NET 和 C#)

有关 Web 应用程序

编写 ASP.NET 程序时,您编写的是将创建 Web 页并与其交互的程序,所以,您的程序不像写几个字符到控制台并等待输入那么简单。您的程序将使用 Web 页与用户通信,并且需要对用户在 Web 页上的操作做出响应。即使在执行像“Hello,World!”这样简单的事情,也必须考虑到这个额外的复杂性。

最早,Web 的目的是分发文档,所以 Web 服务器只会从浏览器获得 URL,并传递对应于该 URL 的磁盘文件(格式化为 HTML)。但是,仅仅传递静态内容并不允许非常复杂的应用,Web 服务器很快进化为支持窗体和各种类型的动态内容。执行该任务的一个常用技术是将窗体中的数据发送到独立的程序,再由该程序分析窗体中的字段,并决定要采取的操作,最后生成要显示在用户浏览器中的响应。

ASP

将 Web 页与运行在服务器上的代码联系起来的一种更流行的方法是 Microsoft Active Server Pages,其更常用的简称是 ASP。在 ASP 中,解释性脚本(通常是 Microsoft Visual Basic Scripting Edition (VBScript),有时是 JScript 或几种其他语言中的一种)建立在 Web 页内部。当服务器处理该页时,它会在读取整个页面的同时解释并执行脚本,以确定要将什么响应发送给浏览器。这种 HTML 和编程语言的集成使编写 ASP 页相对很容易,并且因此很流行。但它意味着编程逻辑(脚本)与包含格式 (HTML) 的相同文件捆绑在一起。

脚本在哪里?

注意,也可以同时采用客户端脚本(在这里,脚本作为 HTML 页的一部分发送给浏览器,浏览器执行代码,通常采用 JScript/JavaScript)和服务器端脚本(正如刚才描述的内容,脚本在 ASP 页中,在服务器上执行,通常采用 VBScript)。

Dr. GUI .NET 系列只讨论服务器端脚本(至少大部分讨论这些内容),至于客户端脚本,至少在数百(如果不是数千)个其他地方可以学习它。

请求/响应模型

回忆一下,在 Web 页中,您将某种 HTTP 请求(如 URL 和窗体中的数据)发送给服务器,服务器则向您返回某种响应(Web 页)。然后,浏览器通常会显示该响应。当您单击各种 Web 页元素时(如,按钮或链接),将发生以下两个事情中的一个:如果 Web 页有客户端脚本代码(与 Web 页一起下载,并且通常采用 JScript/JavaScript),则事件处理程序可能在甚至不与服务器对话的情况下处理该事件。或者,取决于 Web 页元素的 HTML 代码(如按钮),您的浏览器可能将 HTTP 请求发送给服务器。这是当您单击窗体上的 Submit 按钮时通常会发生的事情。

该编程模型可能相当难以使用,因为您必须了解很多有关 HTTP 请求和响应的信息。并且该模型根本不同于大多数 Windows 应用程序(尤其是 Visual Basic 应用程序)所采用的、简单得多的事件驱动的窗体和控件模型。

“经典”ASP 的编程模型是基于 HTTP 请求/响应模型的,它基本上是一种围绕请求和响应的瘦包装程序,通过所包括的基础结构获得请求的字段,并编写脚本来操纵和查询数据,再将输出写入响应中。这是有用的,但我们可以做得更好。

如果您习惯该模型,请不要绝望:您仍然可以与 ASP.NET 应用程序一起并行运行 ASP 应用程序。如果您知道要用应用程序状态做什么以及其他问题,甚至可以将 ASP 应用程序按页转换为 ASP.NET。

基于 ASP.NET 窗体的模型

ASP.NET 中的编程模型添加了根本不同的元素:窗体和控件。由 ASP.NET Web 窗体体现的该编程模型,很类似于 Windows 应用程序的编程模型(尤其类似于 Visual Basic 窗体),尽管编程模型下面的机制非常不同。

从概念上看,纯 Web 窗体应用程序由一组包含控件和 HTML 的窗体组成。控件有属性和方法,并且生成事件。这些事件通常在服务器上进行处理,尽管肯定能够编写客户端脚本来在客户端上处理某些事件。(但这超出了本专栏的讨论范围。)

换句话说,Web 窗体编程模型实际上与 Visual Basic 编程模型相同。所以如果了解 Visual Basic,您将喜欢 Web 窗体。这是比 ASP 模型简单得多的模型。

所以,甚至我们在这里编写的最简单的应用程序都将是完全现代的 Web 窗体应用程序。注意,很有趣的是,用来描述 Web 窗体布局的语言非常像标准的 HTML(主要是增加了几个属性和控件名称)。

现在来看代码……

不再继续啰嗦了,让我们来看我们的第一个 Web 窗体应用程序,这一次使用 Visual Basic .NET,该示例使用嵌入代码、ASP 风格,并且就在 helloinlinevb.aspx 文件中,然后是 C# 的等价代码:

使用 Visual Basic .NET 的 ASP.NET
<script runat="server" language="vb">
   Public Sub doClick(sender as object, e as EventArgs)
      TheLabel.Text = "Hello, world! (from ASP.NET in VB .NET, " + _
         "code inline)"
   End Sub
</script>
<html>
   <head><title>In-line ASPX file in VB .NET</title></head>
   <body>
      VB .NET ASP.NET application with inline code<P><P>
      <form runat="server">
         <asp:button runat="server" text="Say Hello" 
            οnclick="doClick" />
         <p>
         <asp:label runat="server" text="" id="TheLabel" />
      </form>
   </body>
</html>
使用 C# 的 ASP.NET
<script runat="server" language="C#">
   void doClick(object sender, EventArgs e) {
      TheLabel.Text = "Hello, world! (from ASP.NET in C#, " +
         "code inline)";
   }
</script>
<html>
   <head><title>In-line ASPX file in C#</title></head>
   <body>
      C# ASP.NET application with inline code<P><P>
      <form runat="server">
         <asp:button runat="server" text="Say Hello" 
            οnclick="doClick" />
         <p>
         <asp:label runat="server" text="" id="TheLabel" />
      </form>
   </body>
</html>
两种语言之间的差异不大

首先,注意 C# 页非常类似于 Visual Basic .NET 代码。除了代码本身,唯一的更改是将 <SCRIPT> 标记上的语言属性更改为 C#,并且将标题和文本中的“Visual Basic .NET”更改为“C#”。我们可以同样容易地替换任何与 ASP.NET 兼容的语言,如 JScript .NET。

Main 在哪里?

您还将注意到,没有了 Main 方法。您的代码要由 ASP.NET 运行,所以不需要 Main。而是在适当的时候对您的事件处理程序进行调用。这个差异非常类似于从 DOS 转移到 Windows 的事件驱动编程,尤其是在 Visual Basic 中完成时。

那么代码做什么操作?

请注意某些事:首先,我们有一个小的 Visual Basic .NET 子例程(它是采用 C# 编写的、返回 void 的方法),当调用子例程时,它会将下面的 HTML 中名为“TheLabel”的标签设置为我们的消息。这个子例程包含在一个 <SCRIPT> 标记中,该标记指定在服务器上运行该脚本,并且指定代码采用 Visual Basic(或 C#)。注意,我们忽略了所传递的参数,它们用来告诉我们已发生的事件,但现在事件已经发生这一情况才是我们要关心的全部事情。

现在来看用于控制 Web 页布局的 HTML

随后,我们来看 Web 页自己的 HTML 代码。如果您很熟悉 HTML,这部分内容对于您将也是非常熟悉的。除了三件事情:窗体、按钮和标签均以 runat="server" 属性进行标记,按钮被声明为“asp:button”而不只是常规的 HTML 输入按钮,并且还有一个称为“asp:label”的奇怪标签。另外还有一件事:窗体没有了任何有关张贴或操作的说明。

运行我们的第一个 ASP.NET 应用程序

如果使用 Visual Studio .NET 来构建 Web 窗体应用程序,则该应用程序很容易构建,并且当您单击 Run 按钮时它会正确地自动运行。这的确很棒。随后我们将更多地讨论这一点。如果使用 Web Matrix,同样很容易,因为 Web Matrix 包括它自己的微型 Web 服务器,所以如果您不需要,甚至不必安装 IIS。

但现在,让我们使用记事本做所有事情,并由我们自己处理所有文件。

与运行控制台应用程序相比,运行 ASP.NET 应用程序稍微复杂一点。但一旦您完成了设置,它确实非常容易。

首先,必须安装 IIS Web 服务器。在安装 .NET 框架或 Visual Studio .NET 之前,您应当已经完成该操作。如果安装中遇到问题,应当能够安装 IIS 并使用安装程序只重新安装服务器组件。安装 Windows 组件(如 IIS)要在控制面板中进行(在 Start 菜单上,单击 ControlPanel,然后双击 Add/Remove Programs 图标。然后单击左侧的 Add/Remove Windows Components,并选择 Internet Information Service (IIS))。

随后,您需要启用 IIS 作为 Web 服务器。要这样做,请在 Start 菜单上单击 Control Panel,双击 Administrative Tools图标,然后单击 Internet Information Services Internet Information Services (IIS) Manager。(Dr. GUI 使用 Windows XP Professional 和 Microsoft? Windows? Server 2003;如果您使用其他操作系统,情况可能稍微有所不同。)

从 Internet 信息服务控制台,单击在计算机图标旁边的小加号。然后,单击 Web 站点文件夹旁边的小加号。应当看到一个 Default Web site 项,如下所示。


1. 选中 Default Web site 的 Internet 信息服务控制台

如果 Default Web site 显示它已经停止,则需要启动该服务。要这样做,请右键单击 Default Web site 并单击 Start

如果不了解与 IIS 相关的安全问题,而且计算机直接连接到 Internet 却没有防火墙,那么您可能不希望这样做。

您还可以使用 Web Matrix 内置的 Web 服务器来测试您的应用程序您甚至不需要安装 IIS。要这样做,请遵照 Web Matrix 中的操作指导。

现在,Web 服务器已启动并在运行。(完成任务后,可以再次右键单击 Default Web site 并单击 Stop 来停止它。)我们必须做的所有操作是将文件复制到正确的目录,IIS 将自动完成后面的操作。

安装应用程序

要打开正确的 IIS 文件夹,右键单击 Default Web site,然后单击 Open。这将打开 IIS 用于该 Web 站点的文件夹。

Dr. GUI 建议为您的项目建立一个子文件夹(或两个)。Dr. GUI 将他的子文件夹树命名为“DrGUIdotNet/0”用于存放与 Dr. GUI .NET #0 相关的 Web 页。

建立好子文件夹以后,请将 ASPX 页复制到其中。


2. 将 Web 应用程序文件复制到正确的文件夹

运行您的应用程序

最后,转到您的 Web 浏览器并浏览本地机器上的文件。在 Dr. GUI 的机器上,URL 是 http://localhost/DrGUIdotNet/0/helloinlinevb.aspx 和 http://localhost/DrGUIdotNet/0/helloinlinecs.aspx。“localhost”域指的是您的计算机。如果已像好博士一样命名子目录和 .aspx 文件,您将发现上面的 URL 也适用于您。注意,必须使用 http:作为您的协议,如果您试图使用 Internet Explorer 从文件系统中打开 .aspx 文件,您将绕过 IIS,这意味着您的代码不会运行。一旦正确显示出 Web 页,只需单击 Say Hello 按钮,ASP.NET 就将显示欢迎信息。


3. 采用 Visual Basic .NET 以内联代码实现的 Hello World! 应用程序(单击按钮之后)

但请注意,您没有编译任何内容!ASP.NET 自动完成该操作。如果希望更改代码,请直接修改它(Dr. GUI 始终让记事本处于启动和运行状态,只是用 File.Save 将其编辑的内容写入磁盘),然后重新加载 Web 页(如果希望回到原始状态,请单击 Back 按钮)。ASP.NET 自动完成所有更新操作。这是不是很精彩?

这个 HTML 在浏览器中是什么样子的?

顺便说一句,运行应用程序时,可以看到浏览器中出现的 HTML。您将注意到,它与 .aspx 文件非常不同,这些差异是 ASP.NET 自动执行的处理造成的。例如,在您单击按钮之前,Visual Basic .NET 应用程序生成下面的 HTML(C# 版本与它完全相同,只是在下面两个位置将“Visual Basic .NET”替换为“C#”):

单击按钮之前,由 ASP.NET 应用程序生成的 HTML
<html>
   <head><title>In-line ASPX file in VB .NET</title></head>
   <body>
      VB .NET ASP.NET application with inline code<P><P>
      <form name="_ctl0" method="post" action="helloinlinevb.aspx" id="_ctl0">
<input type="hidden" name="__VIEWSTATE" value=
"dDwxMDA3MzE2MzEyOzs+O3sv0P01UevZXFJOLqBbw+4DdQ4=" />

         <input type="submit" name="_ctl1" value="Say Hello" />
         <p>
         <span id="TheLabel"></span>
      </form>

   </body>
</html>

发送到客户端的 HTML 与原始的 .aspx 文件之间的主要差异在窗体中。首先,窗体自己有几个特殊的属性,所以它可以与 ASP.NET 通信。其次,有一个添加的隐藏 INPUT 标记,该标记用来存储正在被查看的页的状态相关数据。最后,所有 ASP.NET 控件(在 .aspx 文件中以“asp”开头的控件)已经呈现为正确的 HTML(在这里是一个输入 Submit 按钮和用于标签的指示范围的文本)。

ASP.NET 自动为 ASP.NET 控件编写 HTML 是非常强大的功能:这意味着,如果使用 ASP.NET 控件,就不必担心要为不同浏览器编写不同的 HTML。而是由 ASP.NET 检测用户在使用什么浏览器,然后为该浏览器生成适当的 HTML。您做的所有工作是使用高级别控件,并让 ASP.NET 处理细节。(但这不能使您省略针对您要支持的所有浏览器对您的应用程序进行测试的步骤。)

单击按钮时发生什么事情

当您单击按钮说“Hello”时,系统将把一个 HTTP 请求发送给服务器,并且 ASP.NET 将从该请求判断应当运行按钮单击操作的脚本代码。运行代码之后,ASP.NET 将使用控件的更新值重新生成页面,并将页面发送给浏览器:

单击按钮之后由 ASP.NET 应用程序生成的 HTML
<html>
   <head><title>In-line ASPX file in VB .NET</title></head>
   <body>
      VB .NET ASP.NET application with inline code<P><P>
      <form name="_ctl0" method="post" action="helloinlinevb.aspx" id="_ctl0">
<input type="hidden" name="__VIEWSTATE" value="dDwxMDA3Mz
E2MzEyO3Q8O2w8aTwxPjs+O2w8dDw7bDxpPDM+Oz47bDx0PHA8cDxsPFR
leHQ7PjtsPEhlbGxvLCB3b3JsZCEgKGZyb20gQVNQLk5FVCBpbiBWQiAuTkVULCBjb2RlIGlub
GluZSk7Pj47Pjs7Pjs+Pjs+Pjs+BQyLRwj8cd6YqwFn4gpQYk2NhTY=" />

         <input type="submit" name="_ctl1" value="Say Hello" />
         <p>
         <span id="TheLabel">Hello, world! (from ASP.NET in VB
 .NET, code inline)</span>
      </form>
   </body>
</html>

在这里,HTML 与以前相同,但有两个例外:首先,隐藏的 INPUT 项的值属性不同;其次,在代码中 TheLabel 被设置成新的字符串,该字符串出现在由标签控件生成的 SPAN 标记中。

您可能想知道 ASP.NET 是否解释您的代码。回答是没有,实际上,ASP.NET 剪下该代码并编译它,并将所产生的程序集存储在专用缓存中。只有当您更改了源代码,ASP.NET 才会重新编译它。通常您不希望或不需要查看所产生的程序集,但随后 Dr. GUI 将向您介绍如何查找它(仅此一次)。

代码隐藏

在传统 ASP 中,VBScript 代码直接混合到 HTML 页中(类似于我们刚才做的),并且通常会把 HTML 代码直接编写到响应中。上面显示了与该方法等同的 ASP.NET。

但 ASP.NET 还支持将代码文件与类似 HTML 的 .aspx 文件分隔开来。这称为“代码隐藏”(code behind)。它的优点是,如果将 HTML 和代码完全地分隔开,编写这二者都将容易得多,尤其是当 HTML 布局和代码逻辑由不同人员编写时,而这是通常的做法。

所有未来的 Dr. GUI .NET ASP.NET 示例都将使用代码隐藏功能,因为显然这样做更好。

我们的“Hello”应用程序将有两个文件:包含 HTML 和对代码文件的引用的 .aspx 文件,以及包含实际代码的 Visual Basic .NET (.vb) 和 C# (.cs) 文件。对于我们的 Visual Basic .NET 版本来说,hellocodebehindvb.aspx 文件类似如下的样子:

使用 Visual Basic .NET 代码隐藏的 ASP.NET
<%@ Page Language="vb" Src="hellocodebehindvb.vb" 
         Inherits="HelloWebFormVb"%>
<HTML>
   <HEAD>
      <title>Web Form</title>
   </HEAD>
   <body>
   VB .NET ASP.NET application with "Code Behind"<P><P>
      <form runat="server" ID="Form1">
         <asp:button runat="server" text="Say Hello" 
            ID="Button1" />
         <p>
         <asp:label runat="server" text="" id="TheLabel" />
      </form>
   </body>
</HTML>

代码内联版本的差异如下:

内联版本的 SCRIPT 段被替换为特殊的标记,该标记指定了在此页将使用的类的那个源文件中的语言、源文件名和类名。

代码本身存在于单独的文件中。

按钮没有指定当它被单击时要调用的方法,因为 ASP.NET 会自动把按钮单击操作链接到该方法。

所有 ASP.NET 控件都有 ID,这样才能从代码访问它们。

除了语言、源文件名和文件名(还有标题和页面上的文字)以外,.aspx 文件的 C# 版本与前面的文件相同。它在与本文同时提供的源代码清单文件中。

代码隐藏类的 Visual Basic .NET 代码很简单:

上面的 Visual Basic .NET“代码隐藏”代码
Public Class HelloWebFormVb
    Inherits System.Web.UI.Page
    Protected WithEvents Button1 As System.Web.UI.WebControls.Button
    Protected TheLabel As System.Web.UI.WebControls.Label

    Private Sub Button1_Click(ByVal sender As Object, 
      ByVal e As System.EventArgs) Handles Button1.Click
      TheLabel.Text = _
        "Hello, world! (from an ASP.NET/VB .NET WebForm with code behind)"
    End Sub
End Class

注意,类名称与在 .aspx 文件顶部由 Inherits 属性所指定的名称相同。所包含的含义是,应用程序的页面类继承了这个类(在这里,这个类就是 HelloWebFormVb,如果使用 C#,则是 HelloWebFormCs)。如果不熟悉继承,现在不用担心太多。我们将在以后的 Dr. GUI .NET 专栏中讨论它。目前,只需这样简单认识它:如果继承了某样东西,就可以使用所继承的东西的所有功能,非常方便吧!

您将注意到,我们的类继承了 System.Web.UI.Page,后者有很多功能可供我们使用。

随后,我们声明了对应于 HTML 中的按钮和标签的变量。注意,名称与 .aspx 文件中的 ID 相同。还要注意,按钮是用 WithEvents 声明的,因为我们将处理它的单击事件。

之后,我们声明单击处理程序。(注意 Handles 子句。)其余代码与内联脚本代码非常类似。

下面是 C# 版本:

C#“代码隐藏”代码
public class HelloWebFormCs : System.Web.UI.Page
{
   protected System.Web.UI.WebControls.Button Button1;
   protected System.Web.UI.WebControls.Label TheLabel;

   override protected void OnInit(System.EventArgs e)
   {
      this.Button1.Click += 
         new System.EventHandler(this.Button1_Click);
      base.OnInit(e);
   }

   private void Button1_Click(object sender, System.EventArgs e)
   {
      TheLabel.Text = 
      "Hello, world! (from an ASP.NET/C# WebForm with code behind)";
   }
}

在继承方面,它非常类似于 Visual Basic .NET 版本,但是,由于 C# 不自动支持用处理程序方法连接事件,所以我们必须显式执行此操作。为了这样做,我们重写 OnInit 方法并连接处理程序,然后调用基类的 OnInit 方法。当我们在随后的专栏中讨论委托和事件时,我们将讨论处理程序连接如何工作。目前,只需知道我们已经声明的 OnInit 方法会在初始化页面时被自动调用,还要知道内部语句会将由按钮触发的单击事件与 Button1_Click 方法联系起来。

当我们在以后的专栏中讨论继承时,我们还将讨论重写和调用基类方法。现在,只需知道这个特殊的语句会将按钮的单击事件交由 Button1_Click方法处理。

使用 Visual Studio .NET 创建 Web 窗体应用程序

使用 Visual Studio .NET 创建 Web 窗体应用程序非常容易。只需用您选择的语言(C# 或 Visual Basic .NET)创建一个类型为“ASP.NET Web Application”的新项目,并将一个按钮和一个标签拖到 Web 页上,然后双击该按钮,即可添加用来设置标签的代码。所有操作只需大约一分钟,包括运行程序以检查结果的时间在内。Visual Studio .NET 非常好用,值得购买!

看见了吗?可以用 C# 和 Visual Basic .NET 交换变量!

好博士刚才提到,C# 和 Visual Basic .NET 不同于其他某些语言(如,Brand J),用这两种语言可以编写一个交换两个变量的函数。下面的程序将交换两个整型变量的内容:

C#
// Compile with: csc swapcs.cs
using System;
class SwapInts {
   public static void Main() {
      int i = 1, j = 2;
      Console.WriteLine("C#: i is {0}, j is {1}", i, j);
      Swap(ref i, ref j);
      Console.WriteLine("i is {0}, j is {1}", i, j);
      Console.WriteLine(
         "i is still {1:####}, and j still is {0:####}",
         j, i
      );
      Console.ReadLine();
   }

   static void Swap(ref int a, ref int b) {
      int t = a;
      a = b;
      b = t;
   }
}
Visual Basic .NET
' Compile with: vbc swapvb.vb
Imports System
Public Class SwapInts ' used class, not module, here...
    Public Shared Sub Main() ' ...so had to declare public, shared
        Dim i As Integer = 1, j As Integer = 2
        Console.WriteLine("VB .NET: i is {0}, j is {1}", i, j)
        Swap(i, j) ' don't have to use "ref" to call!
        Console.WriteLine("i is {0}, j is {1}", i, j)
        Console.WriteLine( _
            "i is still {1:####}, and j still is {0:####}", _
            j, i)
        Console.ReadLine()
    End Sub

    Private Shared Sub Swap(ByRef a As Integer, ByRef b As Integer)
        Dim t As Integer = a
        a = b
        b = t
    End Sub
End Class

在这里要注意到几件事。首先,好博士已经选择使用 C# 类型的 int 和 Visual Basic .NET 类型的 Integer 而不是 .NET 框架类型的 System.Int32 (Int 32 的全名)。因为 C# 中的 int 和 Visual Basic .NET 中的 Integer 只是 System.Int32 的别名,二者完全相同,并且您可以很容易地在 C# 或 Visual Basic .NET 程序中使用 Int32System.Int32

某些程序员更喜欢使用框架类型(如 Int32),但由于示例和文档使用内置类型,所以,Dr. GUI 更喜欢使用内置类型。

如果希望将这些程序中的任一个转换为另一种语言,必须查找新语言中的哪个类型对应于 int/Integer/System.Int32 并使用该类型,或者使用 System.Int32/Int32

其次,注意 Console.WriteLine 提供的灵活格式。变量将插入到输出字符串中,取代大括号 {0}{1} 中的表达式。数字 0 和 1 代表要格式化的参数的位置。第一个参数被编号为数字 0,而不是 1。(就因为这一点,加上数组编号也以零开始,所以本专栏叫做 Dr. GUI .NET #0,而不是 #1。)您将注意到,好博士在最后的 WriteLine 语句中交换了变量的位置。当您要使用不同的语法将格式字符串转换成自然语言时,能够交换顺序是很重要的,因为这样才能在不更改调用的情况下更改格式字符串。此外,也可以像在最后的 WriteLine 语句中一样,将其他格式化信息放在大括号中。该格式化机制还可根据您的类型进行扩展。(我们将在随后的专栏中讨论这个。)

最后,注意 C# 代码中最重要的一点:在调用 Swap 和声明该方法时,按引用传递的参数都被标记为 ref。我们以这种方式告诉 C# 编译器:当我们调用该方法时,我们可能希望更改 ij 的值。如果没有使用 ref,将交换在按值传递值时所生成的副本。(您可以试一试该方式,先删除单词 ref 的所有四个实例,然后自己查看结果。)

在 Visual Basic .NET 中,我们在方法声明中使用单词 Byref 来标记参数,但我们不必标记每个调用,这样做更简单,并且与较旧版本的 Visual Basic 兼容,但这就没有办法通过查看调用区分在 Visual Basic .NET 中您是按引用还是按值进行调用的。

使用 ASP.NET 交换变量

当然,我们也可以用 ASP.NET 程序交换变量。请看下面的 .aspx 程序。(随后将列出 Visual Basic .NET 代码):

ASP.NET

<%@ Page Language="vb" Src="webswapvb.vb" Inherits="SwapWebFormVb"%>
<HTML>
   <HEAD>
      <title>Swap in VB .NET</title>
   </HEAD>
   <body>
   VB .NET ASP.NET application to swap two values<P><P>
      <form runat="server" ID="Form1">
         I:&nbsp
         <asp:textbox runat="server" text="3" ID="I" />
         J:&nbsp
         <asp:textbox runat="server" text="4" ID="J" />
         <p>
         <asp:button runat="server" text="Swap" ID="Button1" />
         <p>
      </form>
   </body>
</HTML>

该页与我们已经看见的其他页很类似。注意,文本(如,“I:”后面是非换行的空格)与 ASP.NET 控件一起分散在页中。这为页面设计提供了巨大的灵活性,而不用担心脚本代码放到哪里。使用代码隐藏,.aspx 页包含了布局及代码(包括将事件和窗体元素联系起来的代码)全部在代码文件内。

让我们看一看 Visual Basic .NET 代码:

Visual Basic .NET

Public Class SwapWebFormVb
   Inherits System.Web.UI.Page
   Protected WithEvents Button1 As System.Web.UI.WebControls.Button
   Protected I As System.Web.UI.WebControls.TextBox
   Protected J As System.Web.UI.WebControls.TextBox
   Private Sub Button1_Click(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles Button1.Click
      ' VB allows properties to be passed by ref, C# doesn't
      ' However, VB generates temporarys, so it's as slow as C#
      ' ...but easier to write!
      Swap(I.Text, J.Text)
   End Sub
   Private Shared Sub Swap(ByRef a As String, ByRef b As String)
      Dim t As String = a
      a = b
      b = t
   End Sub
End Class

同样,它非常类似于前面的程序。主要的差异是我们声明了某些不同的控件(文本框而不是标签),并且在我们的事件处理程序中,从文本框读取值,然后交换它们,最后把它们放回。(当然,也可以用更少的代码行编写该程序,此处的 Swap 函数只不过是表明一种看法而已。如果交换其他变量,它也会是有用的。)

一定要注意到,Swap 方法没有复制字符串,而是交换引用。这是更为有效的做法。

注意:从技术上看,将属性(实际上是方法调用)作为 ByRef 参数传递给方法是不可能的(因为必须传递内存变量的地址,而不是函数)。但您可以注意到,这似乎正是上面的代码在 Swap(I.Text, J.Text) 中做的事情。这是怎么回事?

在这里实际发生的情况是,Visual Basic .NET 正在后台生成代码,这些代码为每个属性创建一个临时值,并将临时值传递给 Swap 方法,然后再将结果复制回属性。(通过在 ILDASM 中查看生成的代码,可以证明这一点,我们随后将在本专栏进行该操作。)

换句话说,即使语法比 C# 语法短得多,所生成的实际代码实际上长度是相同的。Visual Basic 的优点是更容易编程;C# 的优点是它不会隐藏有可能很耗时的代码。

C#

public class SwapWebFormCs : System.Web.UI.Page
{
   protected System.Web.UI.WebControls.TextBox I;
   protected System.Web.UI.WebControls.TextBox J;
   protected System.Web.UI.WebControls.Button Button1;
   override protected void OnInit(System.EventArgs e)
   {
      this.Button1.Click += 
         new System.EventHandler(this.Button1_Click);
      base.OnInit(e);
   }
   private void Button1_Click(object sender, System.EventArgs e)
   {   // have to move from properties to variables...
      string a = I.Text;
      string b = J.Text;
      Swap(ref a, ref b);
      I.Text = a; // and back :(
      J.Text = b;
   }
   // note that references are swapped, strings aren't moved!
   static void Swap(ref string a, ref string b) {
      string t = a;
      a = b;
      b = t;
   }
}

再一次请您不要吃惊,请注意,Swap 方法交换对字符串的引用,而不是字符串本身。正如您所猜测的一样,您自己在对 Swap 方法的调用中,必须为临时变量编写代码。

试一试!


开始编程!

一旦您已经安装了 .NET,就可以使用记事本或 Visual Studio 创建一个文件,并在该文件中包含前面最后一个 C#“Hello World”程序。就是那个在 Main 的最后一行使用 Console.ReadLine 调用的程序。创建新的空子目录,并将文件保存在其中,把该文件命名为 hellocspause.cs(CS 代表 C#)。可以从本文复制代码,或者从新闻组获得代码。还可以自己键入代码,因为它很短,这是更好的方法。

同时,制作一个 Visual Basic .NET 版本,并将文件命名为 hellovbpause.vb。

随后,打开命令提示符,并转到您使用的目录。通过键入命令“csc hellocspause.cs”编译程序(对 Visual Basic .NET 是“vbc hellovbpause.vb”)。(记住,如果需要,要用 sdkvars.bat 设置路径。)

如果查看目录中的内容,将看见 hellocspause.exe(和 hellovbpause.exe)已经创建。通过键入“hellocspause”(或“hellovbpause”)执行该程序,这时,控制台窗口应当显示“Hello,World!(pause) (from C#)”或“Hello,World!(pause) (from Visual Basic .NET)”。

EXE 里面到底有什么?

列出用来存储控制台应用程序的目录内的内容,并注意每个程序只有两个文件:hellocspause.cs 和 hellocspause.exe,与 hellovbpause.vb 和 hellovbpause.exe。.exe 文件非常小,大约 3KB 左右。这本身很简单。

但这些文件内部有什么呢?里面的内容并不是很简单的。在 .exe 文件中,有一个存根加载程序 (stub loader),它是小型本机机器语言程序,用于使系统加载 .NET 运行时并将控制权交给运行时,以便它可以开始执行您的程序。(.Dll 文件没有 .NET 运行时的存根加载程序,因为运行时将由调用这个 .dll 的 .exe 加载。)

但有两个真正重要的部分:一个是元数据,元数据将程序的情况告诉公共语言运行库和可能引用程序内的类型的编译器;另一个是 IL 形式的代码。(您将回忆起 IL 是 .NET 运行时的机器语言。)当运行时将要第一次执行每个方法时,它会把 IL 转换成本机代码,然后执行本机代码。.NET 从不解释 IL;它始终将它编译成本机代码。

使用 ILDASM 获得所有信息

怎样才能看到元数据和 IL?使用称为 IL Disassembler (ILDASM) 的实用工具很容易做到。假定 .exe 文件在当前目录中,只要在命令提示符下键入“ILDASM hellovbpause.exe”(或“ILDASM hellocspause.exe”)。(随后,我们将描述对于 ASP.NET 程序如何这样做。目前只需在控制台应用程序上这样执行就可以了,然后我们将讨论 ASP.NET 的差异。)

您将看见一个类似下面所示的窗口。(这是用于 Visual Basic .NET 版本所得到的结果,C# 版本非常类似。)


4. 键入“ILDASM hellovbpause.exe”后的初始 ILDASM 屏幕

一开始,在“hellovbpause.exe”下面的树显示两个部分:清单,和类 MyApp。因为模块 hellovbpause.exe 有清单,我们可知它是程序集的描述文件。在这里,程序集只由一个模块文件 hellovbpause.exe 组成。

清单

如果双击清单,将看见一小部分元数据,这部分元数据描述了该程序集(应用程序或组件)中所包括的模块(文件)。对于我们的第三个 hellovb.exe,它看起来类似下面这样:

.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )     // .z/V.4..
  .ver 1:0:5000:0
}
.assembly extern Microsoft.VisualBasic
{
  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )     // .?_....:
  .ver 7:0:5000:0
}
.assembly hellovbpause
{
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module hellovbpause.exe
// MVID: {B8F34B08-AB79-4FD6-9B53-3A4792204A71}
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
// Image base: 0x06bf0000

这个元数据只是声明程序集 hellovbpause(版本是 0.0.0.0)包含模块(文件)hellovbpause.exe,并说它使用程序集 mscorlib(版本1:0:5000:0,这是 .NET 运行时的主 DLL)。(上面显示的 Visual Basic 版本也有对程序集 Microsoft.VisualBasic 的相似引用,而 C# 程序不会有这样的引用,除非它们显式使用了 Visual Basic 运行时中的类型。)模块版本标识符 (MVID) 是全局唯一标识符 (GUID),它包含模块 hellovbpause.exe 的该版本的 ID。

模块的元数据

如果选中模块文件名(“hellovbpause.exe”)并按 Ctrl+M,将看到更多的元数据,但这次是模块的元数据,其中包括每个类和方法。(注意,为了简短易读,好博士已经删除了很多内容。)

ScopeName : hellovbpause.exe
MVID      : {B8F34B08-AB79-4FD6-9B53-3A4792204A71}
===========================================================
Global functions
-------------------------------------------------------
Global fields
-------------------------------------------------------
Global MemberRefs
-------------------------------------------------------
TypeDef #1
-------------------------------------------------------
   TypDefName: MyApp  (02000002)
   Flags     : [Public] [AutoLayout] [Class] [AnsiClass]  (00000001)
   Extends   : 01000001 [TypeRef] System.Object
   Method #1 
   -------------------------------------------------------
      MethodName: .ctor (06000001)
      Flags     : [Public] [ReuseSlot] [SpecialName] [RTSpecialName] 
[.ctor]  (00001806)
      RVA       : 0x00002050
      ImplFlags : [IL] [Managed]  (00000000)
      CallCnvntn: [DEFAULT]
      hasThis 
      ReturnType: Void
      No arguments.

   Method #2 [ENTRYPOINT]
   -------------------------------------------------------
      MethodName: Main (06000002)
      Flags     : [Public] [Static] [ReuseSlot]  (00000016)
      RVA       : 0x00002058
      ImplFlags : [IL] [Managed]  (00000000)
      CallCnvntn: [DEFAULT]
      ReturnType: Void
      No arguments.
      CustomAttribute #1 (0c000001)
      -------------------------------------------------------
         CustomAttribute Type: 0a000004
         CustomAttributeName: System.STAThreadAttribute :: 
instance void .ctor()
         Length: 4
         Value : 01 00 00 00    >                <
         ctor args: ()

TypeRef #1 (01000001)
-------------------------------------------------------
Token:             0x01000001
ResolutionScope:   0x23000001
TypeRefName:       System.Object
   MemberRef #1
   -------------------------------------------------------
      Member: (0a000001) .ctor: 
      CallCnvntn: [DEFAULT]
      hasThis 
      ReturnType: Void
      No arguments.

TypeRef #2 (01000002)
-------------------------------------------------------
Token:             0x01000002
ResolutionScope:   0x23000001
TypeRefName:       System.Console
   MemberRef #1
   -------------------------------------------------------
      Member: (0a000002) WriteLine: 
      CallCnvntn: [DEFAULT]
      ReturnType: Void
      1 Arguments
         Argument #1:  String
   MemberRef #2
   -------------------------------------------------------
      Member: (0a000003) ReadLine: 
      CallCnvntn: [DEFAULT]
      ReturnType: String
      No arguments.

...

User Strings
-------------------------------------------------------
70000001 : (35) L"Hello world! (pause) (from VB .NET)"

可以找到 MyApp 的定义 (TypeDef #1) 和两个方法 constructorMain。(没有编写构造函数,但编译器自动提供它。)还可以看见对您的程序所引用的对象和方法的引用,如 System.Console 和它的 WriteLineReadLine 方法。还有几个编译器提供的其他条目,如 System.Object。通过生成 hellovbpause.exe 并使用 ILDASM 对其进行检查,可以看到它们。好博士还删除了程序集和程序集引用元数据,这些内容主要是对刚才显示的清单的复制。最后,您将看见包括在 WriteLine 语句中的字符串常量。

现在全部理解这些内容并不重要,但 Dr. GUI 希望您看到在可执行程序的元数据中是什么内容。他希望您可以看见元数据包含了运行时和编译器需要的、有关程序集及其模块、类型和成员(如方法)的所有信息。

类的元数据

如果在 ILDASM 主窗口中双击 MyApp 类,将看到 MyApp 类的两个方法:constructorMain。还将看到类的元数据。

在这里,类的元数据指示(当您双击它时)MyApp 是从 System.Object 继承而来的,后者是 mscorlib 程序集的一部分:

.class public auto ansi MyApp
       extends [mscorlib]System.Object
{
} // end of class MyApp

IL 代码

如果双击 Main,将看到它的 IL:

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 
01 00 00 00 ) 
  // Code size       17 (0x11)
  .maxstack  8
  IL_0000:  ldstr      "Hello world! (pause) (from VB .NET)"
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  call       string [mscorlib]System.Console::ReadLine()
  IL_000f:  pop
  IL_0010:  ret
} // end of method MyApp::Main

注意,IL 很简单:调用 Console.WriteLine 的过程是:将字符串的指针压入堆栈中,并调用该方法。同样,调用 ReadLine 也很简单:完成调用之后,返回值从堆栈中弹出(然后将该值忽略)。最后,Main 返回到它的调用方。还可以看到 Main 被声明为入口点。

构造函数的 IL 同样很简单:

.method public specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
} // end of method MyApp::.ctor

ldarg.0 指令将复制作为参数传递给该构造函数的 Me(在 C# 中是 this)指针,并调用基类 (System.Object) 构造函数。

现在进行交换……

随后,遵照刚才描述的步骤,首先按照试一试!一节的指导完成前面介绍的 SwapInts 程序:创建源文件、编译和运行。看一看元数据并注意有关 Swap 函数的参数信息。另外,看一看调用 Swap 的 IL 代码和 Swap 函数的 IL 代码。

Main 的 IL 代码中,您将注意到某些 box 指令。由于 Console.WriteLine 接受对象(而不是整数)作为它在格式字符串后面的参数,所以整数必须转换为对象。将非对象类型转换为对象称为“boxing”,该操作使用 box 指令在 IL 中完成。

使用 ASP.NET 尝试它!

随后,让我们来看一个 ASP.NET 程序。如果您还没有运行您的 ASP.NET 程序,请现在按照 ASP.NET 中的 Hello World 这一节中的指导运行它。好博士建议您设置并运行 Web 交换 Visual Basic 程序。

当您希望看到 ASP.NET 程序集时第一个问题可能是如何找到它:如果您像我们现在做的这样手动处理文件,则 ASP.NET 会自动编译您的代码,并把所产生的程序集放到缓存目录中。我们将在本专栏中讨论如何查找缓存目录和您的程序集。

如果您使用 Visual Studio .NET 创建和编译您的程序,会很容易找到程序集。当 Visual Studio 编译您的项目时,它将在您的 Web 应用程序的 IIS 目录中创建一个 BIN 目录,并将编译后的程序集放在那里。

如果您不使用 Visual Studio 并使用 SRC 属性来告诉 ASP.NET 在哪里查找源代码,ASP.NET 将把它放在它的缓存目录中。(并且,在任何情况下 ASP.NET 都会把 Web 页自己的程序集放在该缓存目录中。)

最容易(和最可靠)的查找文件的方式是搜索 Visual Basic 或 C# 文件(如“webswapvb.vb”)的源文件名。请确保搜索系统文件夹。

您将找到这样一个文件:名称包含源文件名,后面是某些额外内容,最后是 .xml 扩展名,如 webswapvb.vb.dbed68e8.xml。该文件包含程序集的基本名称。打开包含这个 .xml 文件的目录,然后在记事本中打开该文件本身。您将在文件中看到的第一项是带有 ASSEM 属性的 PRESERVE 标记。该属性的值就是程序集 DLL 的基本名称。您将在同一个目录中找到这个 DLL,所以对它运行 ILDASM。

您还将注意到某些相似的 .xml 文件,其名称以 .aspx 文件的名称开头。可以使用这些文件找到作为 .aspx 页的编译结果的程序集,然后可以使用 ILDASM 查看这些程序集。在它们中,您将找到一个称为 ASP 的命名空间;在该命名空间的内部,将找到由 ASP.NET 生成并以您的 .aspx 页命名的类。

如果 .aspx 页有内联代码,那么页面类将是从 System.Web.UI.Page 派生的,并且它包含(除其他内容)的一个方法对应于嵌入在 .aspx 页中的每个方法。

如果 .aspx 页使用代码隐藏,则页面类将是从您的代码隐藏类(而它又是从 System.Web.UI.Page 派生的)派生的,并且方法将位于与您的代码相关的程序集中。

好博士在前面提到,在 Visual Basic 程序中,对 Swap 的非常简单的调用会生成很多代码,他答应要对其进行说明。源代码很简单(只有一行:Swap(I.Text, J.Text)),但这一行生成了非常多的代码。这些代码是:

.method private instance void  Button1_Click(object sender,
 class [mscorlib]System.EventArgs e) cil managed
{
  // Code size       52 (0x34)
  .maxstack  2
  .locals init (string V_0,
           class [System.Web]System.Web.UI.WebControls.TextBox V_1,
           string V_2,
           class [System.Web]System.Web.UI.WebControls.TextBox V_3)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      class [System.Web]System.Web.UI.WebControls.TextBox_
 SwapWebFormVb::I
  IL_0006:  stloc.3
  IL_0007:  ldloc.3
  IL_0008:  callvirt   instance string_ 
[System.Web]System.Web.UI.WebControls.TextBox::get_Text()
  IL_000d:  stloc.2
  IL_000e:  ldloca.s   V_2
  IL_0010:  ldarg.0
  IL_0011:  ldfld      class [System.Web]System.Web.UI.WebControls.TextBox_ 
SwapWebFormVb::J
  IL_0016:  stloc.1
  IL_0017:  ldloc.1
  IL_0018:  callvirt   instance string_ 
[System.Web]System.Web.UI.WebControls.TextBox::get_Text()
  IL_001d:  stloc.0
  IL_001e:  ldloca.s   V_0
  IL_0020:  call       void SwapWebFormVb::Swap(string&,
                                                string&)
  IL_0025:  ldloc.1
  IL_0026:  ldloc.0
  IL_0027:  callvirt   instance void_ 
[System.Web]System.Web.UI.WebControls.TextBox::set_Text(string)
  IL_002c:  ldloc.3
  IL_002d:  ldloc.2
  IL_002e:  callvirt   instance void_ 
[System.Web]System.Web.UI.WebControls.TextBox::set_Text(string)
  IL_0033:  ret
} // end of method SwapWebFormVb::Button1_Click

请好好欣赏您的 ASP.NET 程序!

在文档中查找所需内容

Visual Studio .NET 和 .NET 框架SDK 附带了数量众多的文档。但是,查找您需要的内容有时不太容易,因为有三个重叠的文档集合:MSDN Online、.NET SDK 文档和 Visual Studio .NET 文档。大多数文档存在于所有的文档集合中,但通常您将发现所找内容位于不同集合中的不同位置。

MSDN Online

可以从任何连接 Internet 的机器访问 MSDN Online 文档。要查找您有可能需要的 .NET 框架编程信息,需要使用在 MSDN 主页右侧的 .NET Development 链接。这样就可以访问 .NET 框架开发人员中心。

在左侧的 .NET Development 顶级节点的下面,将找到 Visual Studio .NET 节点和 .NET 框架 SDK 节点,其中包含了 .NET 框架节点。在 .NET 框架节点的下面,您将找到大多数框架自己的文档。在 .NET Development/.NET Framework SDK/.NET Framework/Reference/Compiler and Language Reference 下面,可以找到 language references。这是唯一能够找到 Dr. GUI .NET 1.1 的最新版本的地方(在 .NET Development/.NET Development (General)/Columns/Dr. GUI .NET 的下面)。

.NET 框架 SDK 文档

安装 .NET 框架 SDK 时(或 Visual Studio .NET 安装程序自动安装它时),您将在 Start 菜单中 .NET Framework SDK v 1.1 的下面找到所有文档的链接。Overview 链接是开始的好地方,该链接是唯一包括所有文档链接的地方,甚至包括“Tool Developer's Guide”(包含 IL 指令参考,它是 ECMA 规范一部分)。注意,进入 Tool Developer's Guide 页的唯一方式是通过该概述。但是,.NET 框架 SDK 文档不提供有关如何使用Visual Studio 本身的信息。

Start 菜单上,如果单击 .NET Framework SDK v 1.1/Documentation 图标,将显示 .NET 框架 SDK 帮助文件。该文件基本上包含与 MSDN Online 中的 .NET Development/.NET Framework SDK/Product Documentation/ 节点和 Visual Studio .NET 中的 .NET Framework节点相同的文档节点。

Web Matrix 文档

Web Matrix 采用了不同的文档访问方法:Web Matrix 不包括文档,它只包含转到 Internet 上适当文档集合的链接。任何时候只要您请求获得帮助,Web Matrix 就会启动 Internet Explorer 并加载一个页面,而且,几乎所有 Web 页都来自实时的 Internet 站点。

这样做的优点是 Web Matrix 的下载文件可以更小,因为不必包括文档。缺点是,如果当时没有有效的 Internet 连接,就无法通过 Web Matrix 访问文档。

如果希望在不连接的情况下工作,该怎么办?实际上,这很容易:只需下载 .NET 框架 SDK 并使用其中的文档。除了关于如何使用 Web Matrix 自己的文档以外,.NET 框架 SDK 文档还可以提供您需要的所有东西。

或者,只需购买一个 Visual 语言产品或 Visual Studio,就可以获得所有文档。

Visual Studio .NET 文档

最后,如果您已经购买和安装了 Visual Studio,可以从 IDE 内部获得文档。Visual Studio 文档包含关于如何使用 Visual Studio 的所有信息,另外还包括刚才提到的几乎所有信息。从 .NET Framework SDK 节点,或主 Visual Studio .NET 节点下面的各个语言节点,可以找到语言文档。

注意,MSDN Library 节点没有 .NET Development 节点(以及 Networking and Directory Services、XML Web services 和 MSDN Archive 节点)。这些信息的大部分都位于 Visual Studio .NET 节点的下面,但某些(像修订后的 Dr. GUI .NET 1.1)仅联机可用。

文档小结

有时,在文档中查找需要的内容也会有一点困难。有些信息仅联机可用,而有些信息则只在 .NET 框架 SDK 中提供(为 .NET 框架编程的每个人都应当有 .NET 框架 SDK,它可以是独立安装的,也可以是与 Visual Studio .NET 一起安装的)。像任何大的新文档集合一样,需要花一点时间来熟悉它。通常,Visual Studio 有最完整的文档集合(不包括刚才提到的 Tool Developer's Guide 和 MSDN Online 节点)。

所以,应当花少量时间把文档全部浏览一遍,看一看它包括什么内容。您会为拥有这么多材料感到吃惊!

独立地进一步尝试

如果您有一点额外的时间,请修改在这里看到的程序,去做一些有趣的事情,然后运行它们,并使用 ILDASM 查看它们。要在这个过程中获得帮助,请使用文档。您尤其应当看一看下面的部分:

在 Visual Studio 帮助系统中,Visual Studio .NET 下面的 Samples 和 Walkthroughs

在所有文档集合系统中,.NET Framework SDK 节点下面的 Quickstarts

Compiler and Language Reference

.NET Framework Reference

.NET Framework Developer's Guide(在 Start 菜单上,使用.NET Framework SDK v 1.1/Overview

IL Instruction Reference(要查找“Partition III CIL”,请从 Start 菜单中的 .NET Framework SDK Overview 页上,单击 Tool Developers Guide,然后单击 Documentation。)

加入我们!

前面提到过,GotDotNet 为本专栏读者提供了 Dr. GUI .NET 留言板(或论坛)。它的位置是 http://gotdotnet.com/community/messageboard/MessageBoard.aspx?id=46。在这里,您可以询问有关本专栏的问题,并就本专栏展开讨论,这里会有代码。请加入、提问并与其他人共享您学到的内容!

在哪里进一步学习

如果确实希望快速学会 .NET,请阅读一些资料或参加培训课程。Dr. GUI 参加了 Wintellect 公司 (http://www.wintellect.com/) 的作家 Jeffrey Richter 提供的非常好的课程。Jeff 确实精通自己的业务,并且知道如何将它解释好,好博士从 Jeff 的培训课程中受益很多,这些系列文章也是如此。(但是,Dr. GUI 承认他嫉妒 Jeff 与 .NET 运行时团队在同一个大楼里上班,而 Dr. GUI 没有。)其他公司(如 DevelopMentor)也提供课程和资源。

Jeff 的书 Applied Microsoft .NET Framework Programming 尤其写得好。它提供了两个版本,一个针对 C#,一个针对 Visual Basic .NET(http://microsoft.com/mspress/books/6199.asp)。它重点讨论了框架和执行环境,它确实为您进行深入学习提供了所需的背景知识。在此书出版之前,Dr. GUI 审阅了这本书,并且热忱推荐它。它确实非常好。它仅有的缺点是,尚未针对 .NET 框架 1.1 版进行更新。

如果您对 IL 语言的细节感兴趣,请阅读 Serge Lidin 编写的“Inside Microsoft .NET IL Assembler”,其位置是 http://microsoft.com/mspress/books/5771.asp

现在,各种书籍非常多,包括参考文档的打印版本(终于可以获得了!)。请在 http://www.microsoft.com/mspress/net/framework/ 查阅 Microsoft Press 提供的所有出版物。

另外,还有一组 .NET 邮件列表,和一组新的 Microsoft 新闻组。DevelopMentor 邮件列表非常忙,但您可以浏览 Web 上的存档。

您还可以定期访问 MSDN .NET Developer Center,以便了解 .NET 和资源的最新信息。

您可以定期查阅 .NET 框架开发团队的 GotDotNet Web 站点。

本期主题和下期主题

这一次,我们讨论了一点关于 .NET 是什么(尤其是有关 .NET 框架和运行时)的问题,并讨论了它对开发人员的重要意义。我们还讨论了如何获得和安装 .NET 框架 SDK 和/或 Visual Studio .NET,并在命令行和 ASP.NET 中大致运行了几个简单的程序。最后,我们查看了这些程序的元数据和 IL,并花了一点时间大体介绍文档的情况。

这篇文章很长,但 Dr. GUI 承诺以后的文章会更短。我保证。

下回,我们将讨论 .NET 框架的基本单位(类型)并简单回顾面向对象编程,包括 .NET 框架提供的新功能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值