访谈录之C,创建Windows应用程序10bet手机官网:
分类:web前端

ROBERT HESS: 当作一个标准的For循环?

标题    msdn 访谈录之C#编程    rainbow(翻译)关键字    C#,JEFFREY RICHTER出处    ]

标题    MSDN 访谈录之C#编程一    rainbow(翻译)关键字    C#,msdn出处    

 

JEFFREY RICHTER:对,当作一个标准的For循环。因此有时到了最后,它所做工作比我当初想象的还要多。使用foreach是相当常见的,有了它实在是很爽。

程序员天地
Robert Hess和Jeffrey Richter(著名的编程作家、专栏作家和咨询专家)的谈话。

MSDN 访谈录(MSDN Show)
  C#编程

使用 Microsoft.NET Frameworks 创建基于 Windows 的应用程序

Shawn Burke
Microsoft Corporation
2000年9月

摘要: :本文介绍了 Win 表单这一新的窗体程序包,借助这一程序包,开发人员能够充分利用 Microsoft Windows 操作系统所提供的 UI 功能。

目录

  • 简介
  • 介绍 Win Forms
  • 更好的易学易用性
  • 布局
  • GDI+
  • 访问底层系统
  • 结论

简介

目前 Web 已成了街谈巷议的话题,看起来好像 Microsoft? Visual Studio? 开发系统对创建基于 Microsoft Windows? 的传统应用程序的支持有所减弱。实际上,Microsoft 对基于 Windows 的应用程序开发方面的投资在不断加大。

Win 表单是一个新的窗体程序包,借助这一程序包,开发人员能够充分利用 Microsoft Windows? 操作系统所提供的丰富的用户界面功能,创建基于 Windows 的应用程序。Win Forms 是新的 Microsoft?.NET 平台的一个组成部分,它提供了许多新技术,包括通用的应用程序框架、可管理的执行环境、一体化的安全性以及面向对象的设计原则。而且,Win Forms 全面支持快速简便地接入 Web Services 以及建立丰富的基于 ADO+ 数据模型的数据感知应用程序。得益于 Visual Studio 中新的共享开发环境,开发人员能够使用包括 Microsoft Visual Basic? 和 C# 在内的任何支持 .NET 平台的语言创建 Win Forms 应用程序。

介绍 Win Forms

就像刚才所说的,Win Forms 是专用于 Windows 客户机 UI 编程的 .NET Framework 的命名空间。它与 ASP+ UI 程序包(即 Web Forms)共享同样的设计原则,但其类和实现却全然不同。在 Microsoft Win32? API 和 Web 组件之间没有魔术般变形的类。就像所有的 .NET Frameworks 一样,一致性已成为优先考虑的问题。其目的是为了 Win Forms 开发人员能够迅速适应在 Web Forms 中编写代码,反之亦然。例如,所有命名空间都有 Button 类,每一个都有文本、默认的 OnClick 事件以及 ForeColorBackColorFont 属性。

Win Forms 的所有控件都基于 System.WinForms.Control 类。Control 已内置了所有基本的 HWND 功能,并且它能处理我们已经熟悉并喜爱的绝大多数通用 WM_xxxx 消息。RichControl 由 Control 派生而来,其中添加了布局逻辑和绘图代码。System.WinForms 命名空间中的绝大多数控件实际上都由 RichControl 派生而来。ScrollableControl 能够支持窗口客户区域的滚动。一般情况下,对滚动功能的支持是通过 ContainerControl 实现的,后者由 ScrollableControl 派生而来,并增加了对管理子控件、焦点问题和跨栏的支持。Form 由 ContainerControl 派生而来,是 Win Form 的顶级控件,它带有控制标题栏、系统菜单、非矩形窗口和默认控件的属性。UserControl 也由 ContainterControl 派生而来,是开发人员能够创建的控件的基本类。UserControl 一般用于托管其它子控件,但对于外部客户机来说,它又是作为单个单元出现的。UserControl 和 Form 在 Microsoft? Visual Studio.NET 中都有可视设计器,您会找到用于添加和设计由其所派生的类的项。

10bet手机官网 1

图 1. Win Forms 控件层次结构

既然我们已了解 Win Forms 的(最)基本方面,让我们揭开它的面纱,看看其表面下的一些相当不错的功能。

更好的易学易用性

Win Forms 的主要目的是尽可能地提高定位到 Win32 平台的开发人员的工作效率。无论是图形设备界面 (GDI) 还是窗口状态管理,为 Win32 编程通常都是很困难的。例如,类似 WS_BORDER 或 WS_CAPTION 的一些窗口样式只能在创建窗口时指定或修改。而 WS_VISIBLE 或 WS_CHILD 等其它窗口样式则可以对已创建的窗口进行修改。Win Forms 尽力消除了这些细微的差别,并确保操作过程始终保持一致性。可以随时地、不限次序地对 Win Forms 控件的属性进行设置,总能产生预期效果。如果改动过程需要创建新的 HWND,Win Forms 框架能够自动地、透明地重新生成窗口,并为其应用相适宜的所有设置。

由控件获得通知或事件在 Win Forms 中也要容易得多。Win Forms 事件都基于称为 Delegates 的一个通用语言运行时功能。Delegates 从本质上讲是对类型安全的、可靠的函数指针。对于任一控件的任一事件,都可以添加代理处理程序;绝不会强迫您创建派生类以通过替代处理事件,创建事件映射,或仅为处理一个事件而为类的所有事件实施一个接口。也可以通过替代派生类处理事件,但这种方式一般用于控件创建者或更为高级的应用。汇集某一按钮的 Click 事件相当简单:

public class ButtonClickForm: System.WinForms.Form {

private System.WinForms.Button button1;

public ButtonClickForm() {

// 创建按钮

button1 = new System.WinForms.Button();      

// 添加处理程序

button1.AddOnClick(new System.EventHandler(button1_Click));

// 将按钮添加到窗体中

this.Controls.Add(button1);

  }



private void button1_Click(object sender, EventArgs e) {

MessageBox.Show("button1 clicked!");

  }

    }

这里,我们创建了一个按钮,并添加了一个名为 button1_Click 的处理程序方法,通过短短几行代码,在单击该按钮后,将调用这一方法。请注意,即使处理程序方法被标记为专用,创建这一挂钩的代码仍可以使用该方法,单击按钮后,按钮将能够激活这一方法的事件。

启动 Win Forms 项目的过程也得到了简化。使用 Visual Studio.NET 创建 Win Forms 项目的过程只会创建一个要编译的项目文件:Form1.cs。没有头文件,没有接口定义文件,没有引导程序文件,没有资源文件,没有库文件。项目所需的所有信息都包含在窗体的代码中。这样做有一个好处:项目由一个简单的单窗体应用程序扩展到复杂的、带有多个代码文件的多窗体应用程序要方便得多。链接过程不需要中间对象文件,只有代码和已构建的、受管理的所有 DLL。只要您习惯了这一方法,就能明显地感觉到创建 .NET Framework 应用程序和创建 C/C++ 应用程序之间复杂性的不同。因为信息仅仅包含在代码文件中,在 Visual Studio.NET 环境外创建版本的过程也非常容易,无论是 Visual Basic 代码、C# 代码,还是任何其它语言编写的针对 .NET Framework 的代码。

因为 Win Forms 建立在通用语言运行时的基础之上,开发人员可以任选目前针对通用语言运行时的众多语言中的一种,构建 Win32 应用程序。开发人员现在可以使用多种语言编写 Win Forms 应用程序(或 Web Forms 应用程序或 Data 应用程序):从 C# 到 COBOL 到 Eiffel 再到 Perl 等等,中间还有很多种(上一次计数是 17 种)。方便易用再加上广泛的应用场合相得益彰,为开发人员提供了深厚的基础,使他们能够迅速有效地使用 Win Forms 构建实用的应用程序。

布局

如果您曾尝试创建能够正常调整大小的窗体,您就会知道这一过程有多么困难。Microsoft Foundation Classes (MFC) 或早期的 Visual Basic 版本没有对这一功能提供内置的支持。然而现在只需几行代码(通常情况下您甚至不需要编写这些代码,因为在设计时就能通过 Property Browser 实现这些功能!),即可创建能够正常调整大小的对话框。

基本布局由两条组成:Anchoring 和 Docking。RichControl 有一个 Anchor 属性,它是一种枚举类型,可以用“或”操作将这些值组合在一起,以说明控件将与其父控件的某一边保持恒定距离。例如,如果您将一个按钮置于窗体上,并将 Anchor 属性设置为 AnchorStyles.BottomRight,则在调整按钮的大小时,按钮将与窗体的底边和右边保持同一距离。此外,如果将 Anchor 设置为 AnchorStyles.All,则按钮的各个边都与窗体的对应边保持同一距离,在调整按钮大小时仍要满足这些约束条件。

Docking 实际上是 Anchoring 的一个特殊情况。RichControlDock 属性说明控件要将自身固定到其父控件的哪一边。Docking 可以是 Top、Left、Right、Bottom 或 Fill。在每种情况下,控件都将移动到尽量靠近指定边,并调整其大小,以填满那一边。如果父控件的大小有所调整,这一状况仍将保持。将一个控件移

Microsoft.NET Frameworks 创建基于 Windows 的应用程序 Shawn Burke Microsoft Corporation 2000年9月 摘要: :本文介绍了 Win 表单这一新的窗体程序包,...

ROBERT HESS:我猜您本来也应当在那里放置一个计数器,不过这会完全使foreach不起作用。

  • *ROBERT HESS: 欢迎回来。我们正要涉及到有关C#编程方面的问题。为了有助于我们理解这些问题,我邀请我的好朋友Jeffery Richter到这里来。Jeffery恰好是一名撰写了很多编程书籍的程序员,他最新的一本书为Programming Server Side Applications for Windows 2000。现在您也是一位咨询专家并且拥有自己的公司Wintellect,是吗?

C#是一种令人耳目一新且为之一振的编程语言,它设计给C++程序员带来快速的开发能力,而又不牺牲C和 C++所特有的功能和控制。
    在今天的这一期里,我们将要和Anders Hejlsberg交谈,他是微软一位资深的工程师,一直帮助设计、开发和实现该语言,并发挥其在未来.NET平台中的作用。我们还要和Jeffrey Richter(著名的编程作家和咨询专家)交谈,他从事C#的工作已经一年有余了。

JEFFREY RICHTER: 是的,很正确。

JEFFREY RICHTER: Wintellect。

介绍

ROBERT HESS:那么,您认为C#还另外具有什么样很酷特性,以让观众说,好,这就是我要选的语言?

ROBERT HESS: 我猜您有一个网站吧?


JEFFREY RICHTER:嗯,正如Anders在前面指出,C#是完全基于组件的,在那里具有事件,具有接口,具有属性,它们都是一等公民,所以没有下滑杠,没有下滑杠属性等任何类似的东西。出身于C#的人应当熟悉异常处理,因为遇到错误时,就调用在基类库中的framework里的错误处理程序。因此我在屏幕上写了一小块代码,以示范如何进行适当的错误处理。我具有一个try语块,再强调一下,您应注意在try这个单词的前面没有下滑杠,因为在C#语言中它位于第一阶层。我new一个文件流对象,这是打开磁盘里的文件的一种方式。而在双引号里,我给出了我们希望打开的文件的路径名。
using System;
using System.IO;

JEFFREY RICHTER:有,Wintellect.com。我们专门从事培训、调试和广告。

Robert Hess,微软产品经理和“Show”节目主持人。

public class App {
   public static void Main() {
      FileStream fs = null;
      try {
         fs = new FileStream(@"C:NotThere.txt", FileMode.Open,',',');
      }
      catch (Exception e) {
         Console.WriteLine(e.Message,',',');
      }
      finally {
         if (fs != null) fs.Close(,',',');
      }
   }
}

ROBERT HESS: 好了,我了解到您最近做了不少有关C#的工作。

ROBERT HESS: 让我们继续关注理解.NET体系(Architecture)。我们今天将关注新的C#(念“C Sharp”而不是“C Pound”!)编程语言。首先看看MSDN 消息更新栏目。

ROBERT HESS:等等,那是一个错误,是吗?

JEFFREY RICHTER: 是的,至今已一年有余了,我花了很大的精力一直专攻C#的编程。

MSDN 消息更新

JEFFREY RICHTER:不,这正是我要指出的。因为C#有一个非常酷的特性,可以给字符串加上一个@符号的前缀,使我们转用原义字符串(verbatim  string,即真正的字符串,不加任何转义符),这里只允许使用单反斜杠“”而不是双反斜杠“\”。而长路径实在是一种十分常见的C++编程错误,人们以反斜杠代替双反斜杠,文件就不能正确地打开。在这种情况下应用加上"n",意思是要换行。所以,这实在是一个巧妙的特性。不象一个file stream,因为人们熟悉Win32的CreateFile函数,当该函数无法打开一个文件时就会返回无效的句柄值,或返回-1意味着失败。在.NET framework中,当我企图打开一个不存在的文件时,就会引发一个异常,所以我在这里设置了一个catch语块,设法捕获到异常,这是一个非常简单的catch语块,只把信息输出屏幕,看看可能做了些什么,接着我又设置了一个finally语块,在这里的代码要确保能执行,因此假如我在try语块中有很多行真正涉及到文件操作的代码,在打开文件之后,finally语块就会执行并在最后明确地关闭文件。这实在是一种很巧妙的特性,Win32甚至是C++也不曾拥有,它能够使try,catch和finally浑然一体,真正算起来,这种操作我们以前从未遇见过。

ROBERT HESS:已经有一年了?我想我们才刚发布了C#。


ROBERT HESS:我认为当应用程序变得越来越复杂时,人们在其中进行错误处理是相当重要的,当企图创建文件或进行类似的操作时,出错的机会可能会很多。尤其是使用其他人的对象和类似的东西时。
    那么,这是不是意味着在编写C#的应用程序时,您必须保证函数和方法都能正确地设置异常并抛出一个异常,以便人们可以捕获它?

JEFFREY RICHTER:是的,可我一直在圈内,在Microsoft的圈内,如果您愿意的话。我自己在第42楼安置了一个小小的办公室,并在那里从事C#的研究和有关.NET这方面的工作,到现在已经一年多了。

由技术编辑Erica Wiechers主持
(略去与C#无关的谈话)

JEFFREY RICHTER:嗯,绝对如此。良好的编程典范规定:当编写一个函数时,必须验证所有传递进来的参数,如果任何一个参数不合乎要求,就应当明确地引发一个异常,而在基类库中定义有大量的异常类,所以可以轻而易举地使用其中的一个。但是您同样也有能力定义自己的异常类,或许,要查找数据库中的、顾客(customer),却好象没有发现他们的名字,故可以创建自己的customer异常,并在代码里的某个地方引发它。

ROBERT HESS: 这样微软就会对您有所帮助,因为您并不是微软的职员……

技术闲聊(TECHNO BABBLE )

ROBERT HESS:或许会用类似customer的名字作为损坏的customer名……

JEFFREY RICHTER: 对。


JEFFREY RICHTER:是的,大概这样。如果它是"Robert",就是你一直想要引发的异常。

ROBERT HESS:他们只是帮助您的把C#当成一种语言理解,那么您就可以写出更多象这样的书?

Robert Hess和资深工程师Anders Hejlsberg会面,要讨论…???

ROBERT HESS:那么,您认为C#作为一种编程语言将如何发展?当您的客户参加培训时您对他们有什么点拨,他们对此又有什么想法?

JEFFREY RICHTER:是的,他们希望我写更多的书,我得到了帮助,发现了bug,出席了类似的一些规范会议,并与人们交流,因此我觉得学到了很多的东西,而不只是写书,而事实在某种程度上也对C#做出了贡献。所以我可以告诉您,当最初开始时,我感兴趣的第一个东西就是这种新的语言,我将用它来写所有的代码,我知道这些代码是为可以预见的未来写的,让我们暂且不提。我具有非常深厚的C、C++背景,在阅读与C#相关文档和编程参考等资料一个星期之后,我就觉得已经相当精通C#了。并且在一周之内,我能够真正地写出一些有用的东西。

ROBERT HESS: 欢迎回到这个栏目。好了,就象任何一个要在其上面开发软件的平台,为了使这些应用软件能真正地运行起来,所需要的一个主要东西就是一种编程语言。目前,.NET已经拥有了一种专门为此开发的专用语言,我们称之为C#。今天和我们在一起的是Anders Hejlsberg,他是微软一位资深的工程师,在C#语言以及.NET平台领域都扮演了一个关键的角色,在以前的“show”节目里大家都见过他。所以我邀请他到这里来,和大家一起谈论C#,谈谈它是什么,有了它程序员就可以从中得到什么好处,以及它是怎样真正地影响到应用程序的开发的。
那么,您究竟从事C#哪方面的研究工作,是从什么时候开始的?

JEFFREY RICHTER:嗯,我真的认为它将获得巨大的动力。我说过,去年我一直专门用C#编程,偶尔也用C++,但现在却很少用了,而我相信许多VB程序员也将会转向此语言,因为C#更适合公共语言运行库。所以,我真的认为它将获得巨大的动力,并且真正得到重用。在我的培训班里,似乎每个人都喜欢它,事实上一些人说他们参加这个培训班,只是由于这个班开设了C#编程的课,但很快他们就高兴地发现课程也涵盖了framework和类库。

ROBERT HESS:仅仅一周之后。

ANDERS HEJLSBERG: 在最近大概两年半的时间里,我们一直在从事C#的研究工作。设计小组由4人组成,而且在这段时间里,我把主要的精力都放在了这上面。要知道,对于一种新的编程语言,我们有许多事情要去做。我想首先也许就是为程序员提供方便,使程序员开发出更多的产品就是最终目标。如今,虽然在产品的收益方面仅仅只是初具规模,但可以说,我们的目标,在某种意义上,不但要使C#具有C++强大的功能和出色的表现,而且还要使其具备简单易用以及RAD(Rapid Application Development,快速的应用程序开发)语言的生产率。
我们已经做了一些工作,例如,涉及到程序员如何利用更好的工具编写组件的范畴。如果你看看我们是怎样写应用程序的,应该是曾经怎样写应用程序的,如果回顾过去,也就是说5年或10年以前,应用程序就是这样铁板一块地被创建的,它和操作系统的唯一交互,你知道,就是进行文件的i/o操作,而且无论如何操作系统都会载入应用程序,接着用户就与其交互,最后退出。看看现在我们是如何创建internet应用程序的,相比起来简直是天壤之别。应用程序不再是铁板一块了,而是由一系列更小的组件构成,它们分别栖息于不同的环境。例如,你可能拥有类似存储过程(stored procedures)和SQL Server那样的组件,也可能拥有栖息于浏览器中的控件,或者是存在于ASP网页中的代码。商业对象生存于中间层,调用整个集合的组件就等于调用该应用程序。于是为了使……

ROBERT HESS:那么,当谈到.NET framework和类库时,您认为它们怎么样,以及它们是怎样帮助应用程序开发的?

JEFFREY RICHTER:是的,仅仅一周之后。因为它和C++非常类似,您知道,那里的大括号是相同的,返回值是相同的,参数是相同的,许多东西都是相同的。

ROBERT HESS: 而当时您明白其中的每一个组件都比5或10年前的一个应用程序更加复杂。

JEFFREY RICHTER:我认为,这个平台表现很出色。我使用整个平台已经一年了,并且我最近一直在为微软开发一个项目,以展示微软的许多技术。我和另外一个家伙一起工作,他的名字叫Tom,我们要在早上碰头,要在电子白板上继续讨论,接着要…… 这里就是我们今天将要补充说明的性能,我们又要讨论一会儿,我们要表示,这就是当天结束时我们的目标,通常在午饭之前我们要全部完工。我们总是超额地完成了任务。

ROBERT HESS:当继续使用对象、析构函数、构造函数、双冒号(::)等这些老掉牙的东西时,您似乎就要失去他们所拥有有的某些奇特的命名习惯,对吗?

ANDERS HEJLSBERG: 噢,绝对,绝对。同样,为了减少创建组件的复杂性,不象那种大块头程序,每当必须创建其中的一个组件时,就不必另起炉灶,而应该尽量继承一些早已存在于这些专门的栖息环境(hosting environment)中的东西。如果要写浏览器中的一个控件,就要继承一个基控件;如果要写中间层的一个商业对象,就要继承某些商业对象类;而要想公开属性、方法和事件等等,就要说明它们是如何通过把属性与组件联系一起,以便与栖息环境相结合。而且还要能够为这些组件撰写随组件一起发布的文档。

ROBERT HESS:您认为C#和.NET的结合有助于完成工作吗?

JEFFREY RICHTER:是的是的,双冒号(::)都被点号(.)代替,箭头号(->)也被点号代替,这样就大大地简化了该语言。因而对于我来说实在是太容易啦,而且它还具有时效性,我仍不得不回过头去查看该语言参考资料,或许查找如何重载运算符,或者某些很平常的东西,要知道,当我编程时,极少做一些模糊不清的事。而现在大多数东西对我来说是再自然不过的了。事实上要解决的只是流程问题。

ROBERT HESS: 所有的这些只是标准的面向对象的编程,Smalltalk 拥有此特性的时间似乎已经不短了,并且……

JEFFREY RICHTER: 噢,当然。毫无疑问,因为所有的测试都已完成。所有的测试——我们如何公开这个东西,我们能不能使这成为一个方法,能不能把它放在DLL里,能不能使其成变COM 对象,我们应拥有什么类型的接口。所有的这些问题涉及到您如何把这些连接起来并传递指针,保持连接以便可以同步,所以您就可以通过保持和其他人同步来通知他们,所有这些论点都刚刚被引进该平台。因此,自始至终地,我们愿意工作一个小时,我们要完成某项工作,我们会……,然后我们又要坐回去并开始增加其它的东西。我们的生产率如何,确实令人难于置信,而且也同样充满着乐趣。我们确实增加了惊人的图形图像库和alpha混色(blending)以及所有类型的东西,这些以前我们从未处理过alpha混色此类东西。我曾经从事过图形图像的工作,但已经过了好多年了。而利用相应名字空间中的system.drawing语句,我们就能够构造这些图像并对它们进行覆盖和alpha混色,然后又从我们的web服务器返回这些图像给在任何机器上运行的任一客户,甚至不必是一台Windows机器。

ROBERT HESS:既然您从事这项工作已经一年多了,那么您注意到了在这段时间里这种语言自身的演变吗?是否它们今天仍然与一年以前的十分相同?

ANDERS HEJLSBERG: 嗯,绝对如此,现在并不是不能做这样的事。但如果注意一下这种今天已经得到了广泛应用的编程语言,它们实际上并不真正支持面向组件的概念。如果你当初同意我们什么时候谈论组件,那么认为它们具有属性、方法和事件在当今是极其平常的。但如果注意一下C++,就会发现它仅仅提到“方法”这个概念,没有属性,也没有事件。现在,你可以利用命名模式来仿真它们,也就是说,对于一个属性,可以用一个get color和一个set color的方法来取代一个color属性;而要代替类中作为第一个类成员的事件,你拥有的用于接收事件的接口就应该被实现,为了这样,你就必须处理一些琐碎的事……

ROBERT HESS:我想这带来了有利的选择。迄今为止,我们一直在谈论用C#和.NET framework等进行应用程序的开发,并且我了解到您原来就是一个货真价实的应用程序设计师,编写Windows应用程序和标准的GUI程序。令人意外的是web出现了,因此每个人都想到编写web应用程序,或编写运行在浏览器内部基于HTML的应用程序。但现在以一句话对您的产品进行概括,您正在谈到具有这种alpha合成标准的Windows图形应用程序,也谈到了访问web并以相应的格式返回给其它系统。那么象您我这样的Win32应用程序开发者,对传统的应用程序开发环境以及新的web应用程序与.NET的混合有什么看法?

JEFFREY RICHTER:我认为十分相同。但肯定存在着一些小技巧(tweak),在beta测试阶段确实存在着这些回应,存在着许多非确定性的析构函数(non deterministic destructor)、对象的析构(destruction of objects)等类似的东西。因此,基类库已经增加了一个iDisposable接口,我想它将会出现在beta 2.0版中,而不是在beta 1.0版中。同时C#已增加了一些新的语言结构,以帮助你获得与对象的确定性析构(deterministic destruction of objects)关系密切的东西。所以我要说,微软已经十分在意人们对该语言的评价了,并且他们还企图在其中加入新的东西以做出回应。我同样了解到,将来在1.0版之后,他们计划要增加泛型(generics),这有点类似C++中的模板,而我可以肯定,为了支持这些性能,C#就要发展。实际上当处于公共语言运行库(common language runtime)之中时,所有的语言都能用到泛型。

ROBERT HESS:嗯,部分原因是由于C++是基于C的,它只是象预处理程那样,又由于C本来就不支持,C++也不支持……

JEFFREY RICHTER:嗯,我实际上在做的就是这种特别的事情,它不是Win32图形应用程序,而是一个web窗体(form),随意一个web窗体。
ROBERT HESS:那么它甚至也不是一个传统的Windows应用程序吗?它听起来很象啊。
JEFFREY RICHTER:嗯,它真正是什么?实际上它比传统的Win32程序具有更复杂的体系。它实际是一个web服务,并且我认为它是第一批公用微软web服务(public Microsoft web services)之一,是免费的,所以我会给出URL地址。因此谁都可到那里去摆弄摆弄,这个地址是teraserver.Microsoft.net。
ROBERT HESS:噢,我会把这个地址放在本记录稿的后面,以便大家点击访问。
JEFFREY RICHTER:那里有许多微软技术的广告宣传,其中包括Windows 2000 Datacenter、SQL 2000、IIS、ASP.net、.NET frameworks、web services和web forms。所在的资料都在那个网站上。有一个具有图像信息的teraserver web服务,它显示立体地形图和常规像片里的图像和标题。而且我们也有一个人口普查(census)服务,所以可以到那里输入纬度、经度等,便得到相应的城市名以及生活在该地区的人口。我们还有地标(landmark)服务,给出一个以经纬度标定的矩形区,就可以找到该地区范围内的医院和学校。因此,它们是三个单独的web 服务。它们本来可以由不同的公司实现,但实际上都是由我们实现的。接着我们编写了一个web窗体应用程序,它本来可以由任何公司编写,但这次又由我们编写,以便弄清概念,它向这三个不同的web服务发出信息,接着从teraserver获取标题信息,从landmark服务器获取地标信息,然后我们就能够把这些信息载入地图。

ROBERT HESS:因为它们是其中的一部份,又因其是公共语言运行库,所以它们有权使用所有的那些功能。那么您认为,C#作为一种语言总的来说究竟怎么样?

ANDERS HEJLSBERG: 是的,实际上我多少认为,你所看到的就是从C到C++再到C#的发展过程。从C到C++,面向对象编程的概念被加进去了。如果你经历了从C++到C#,那么我会说,面向组件编程的概念也已经被加进去了,而它们之间真的存在着某些相似的地方。就象可以用C代替C++进行面向对象的编程,你也可以用C++代替C#进行面向组件的编程,只不过是更困难而已。用C来进行面向对象的编程是极其困难的,你必须手工地布置V表(虚拟函数表),并且还要处理所有琐碎的事情。用C++写组件也确实可行,但必须要为属性手工地设置命名模式(naming patterns),必须实现事件同步(event syncs),必须具有外部的IDL文件,在文件中可以对栖息属性(hosting attributes)进行描述,必须具有外部的文档文件,等等。我们只真正采纳了其次一个合理的步骤,它反映了人们是如何编写应用程序并把其整合到语言中的

ROBERT HESS:使用alpha混色。

JEFFREY RICHTER:嗯,正如我所说的,C#与C++非常相似,所以我很快便熟悉了。它非常非常的干净,我要说它是非常干净的。我出身于C++背景,尤其是作为一个Windows C++程序员。ANSII拥有C++规范,微软为了展示Windows中的功能,就想在C++中保留一些技巧,并且使这些技巧看起来有点像C++中的贵族,可它们从来就没有真正地达到要求。而微软仍陆续增加__try、  __finally 和 __declspec等类似的东西。

ROBERT HESS: 那么,最初的一些目标是什么?仅出自内心的看法,当您第一次着手这个项目时,您要解决的问题和要确定的这种新语言的方向是什么?

JEFFREY RICHTER:嗯,对,使用alpha混色。于是,这些信息被送回web窗体,送回运行在任何机器上的客户。我们甚至可以增加这样的功能,当鼠标移到某东西上方时,提示工具将会显现并告诉您该网页上相应的学校名和医院名。此范例功能之强大,简直令人无法相信。事实上客户可以是运行任何操作系统的任何机器,并且我们在服务器端利用Windows 2000的GDI+性能处理alpha混色,以及此类高级图形操作,不过我们只把位图(bit map)送回给客户,我再次认为,其功能之强大、生产率之高,简直令人信难于置信。而且我也了解到许多应用正在朝这个方向发展。

ROBERT HESS:这就是您正在谈论的C#。

ANDERS HEJLSBERG: 嗯,我认为正如您所说,面向组件只是一方面。我想另一个关键的因素就是简单化。使编写应用程序更加简单化,不让程序员做一些琐碎的事,机器可以代你做。大量的简化取决于.NET runtime本身,但也取决于语言。基本上,最终我们所做的,就是让你把更多的时间、更多的精力放在算法上,而让系统去做一些琐碎的事。我认为,许多其它非常关键的事情比较现实,我总不能吩咐人们把他们现有的代码通通扔掉吧。我们必须找到权衡的方法,并不仅仅是你的编程技巧,而且还包括你以前编写的、早已存在的代码。因此在C#里,以权衡你技巧的名义,我们努力坚持在与C++的基础语法最接近、最真实的地方。所以用了C#,C++程序员会立即觉得很眼熟、很亲切。

ROBERT HESS:所以您真的很喜欢web应用程序的整个web模型。
JEFFREY RICHTER: 喜欢。

JEFFREY RICHTER:对,当然还有C++。因此,这种语言确实有点恐怖,过了一会儿您还是不会完全弄明白,就如const的用法,当声明一个指针或者是一个常量指针时,星号(*)究竟应放在它的前面,还是放在后面?您将无法断定这些修饰符到底应放在该行的那个位置。我总是需要查资料。因此在C#中,由于微软在设计时已经预先向ECMA(欧洲计算机制造商协会)做出了要求标准化的提议,所以它实在很干净,例如,没有什么是以下滑杠开始的。当然,由于本来在.NET runtime中就没有真正的指针,所以在您的代码中,从头到尾都不会能见到*号和&号等此类修饰符。这样当考虑它时,看起来干净,真的觉得很爽。

ROBERT HESS: 您的所做的一切应当以C语言为基础,是否就是当初的思路之一?或者您是否原来就认为,让我们应与过去彻底决裂,再开始设计一种全新的语言?

ROBERT HESS:即使您是一个传统的Windows应用程序开发者。
JEFFREY RICHTER: 是的。

ROBERT HESS:难道您不觉得缺少什么吗?我的意思是,当我在用C编程时,喜欢运用指针解决问题,对指针重新分类,利用指针算法等老掉牙的东西,您就会从中获得极大的乐趣。难道您在用C#时就不怀念它吗?

ANDERS HEJLSBERG: 嗯,我想这种语言应该以一种崭新的面貌出现,可是我们明白,必须让C和C++程序员熟悉这种语言。当然那就意味着在某种程度上,我们必须把语句结构从弯曲的大括号变换成其它一些东西。我们已经打下了一些基础,但仍然存在着其它某些关键的规则,譬如允许写健壮的软件,这就意味着象垃圾回收(garbage collection)、异常处理、类型安全这样的功能,根本地改变了设计该语言的思路,非常难于上手,以后也不容易扩展。我的意思是说,在C++中,C++语言拥有的一个强大功能之一,但有时也同样是难点之一,事实上您知道,就是没有类型安全。如果你了解清楚自己要做什么,就会从中获取巨大的力量,否则,只是自找苦吃。在C++中,获得一个虚悬指针(dangling pointer)易如反掌。同样,覆盖掉一个数组的尾部,或者拥有一个未初始化的变量等等,也是极其容易事情。而我们需要解决这些难题。我认为,我们不能只从 C++着手并扩展它。而真的必须以退为进,以C++的灵魂设计出新的方案,而这些我们已经差不多完成了。

ROBERT HESS:您现在已横下心来要朝这个方向发展了。

JEFFREY RICHTER:嗯,我不得不承认,我自己总是有些喜新厌旧,但有时也有点念它。当然总的来说,有了C#和.NET framework,您就可以始终与其它语言进行交互操作(interoperate out),因而如果真的必须那样做的话,我便用C++而不是C#编程了。C#也确实提供了一种不安全的关键词(unsafe keyword),这样一来,您就可以创建一个方法并且说,这是不安全的,您有权使用指针并对内存进行直接操作。尽管如此,我还是从未亲自体验过。至于编码时获得的乐趣,.NET framework和基本OS类库提供了大量的特性,它们使编程变得有趣了。因此,当我不能保留虚拟内存并稀疏地提交,也不能在.NET framework中利用内存映象文件进行工作时,至少不能直接进行时,也可以通过交互操作完成,仍然还有其它类似serialization和web服务等东西,它们有利于创作出真正有价值的应用程序,真正强大而丰富的内涵。

ROBERT HESS: 那么其它语言呢?您注意到这些语言在做了什么吗?是否它们就是Pascal 或 Modular 2 或 FORTH,您从中得到什么借鉴?

JEFFREY RICHTER:是的,我已下决心了。程序要能在任何地方运行,并在服务器上进行工作。所有的这些便构成了所谓的分布式系统(distributedness),服务器可以位于三台不同的机器,噢,维护所有的这些资料的SQL Server还可以是另一台机器,web 窗体服务器也位于不同的机器,并且还可以被不同的公司细调以便随意使用这些材料,他们觉得这些材料适合于生成内容丰富的应用程序,而这些程序运行在能被internet访问到的任何地方。这简直令人难于置信,确实难于置信!

ROBERT HESS:如今在您的培训班里,您正在教授和灌输这样的东西,您还在办C#的培训班吗?

ANDERS HEJLSBERG: 绝对!噢,我们考虑到,嗯,我的意思是说,我本人出身于深厚的Pascal背景,所以,自然要考虑到Pascal, Modula, Oberon, 要考虑到Smalltalk,Java,C++以及所有的语言。要知道,今天它们能生存下来并得到了应用,且或多或少地传播开了。

ROBERT HESS:某些迹象告诉我,所有的这些东西给您留下了现象。

JEFFREY RICHTER:是的,事实上刚好这一周,我给第一个C#编程班上课,当时班里有两个Visual Basic程序员,他们根本就不是面向对象的程序员,而我也没有真正地给他们介绍过C#语言,因为我把重点放在公共语言运行库和基类库方面,有关C#的内容想稍后再讲。但是,这两个VB程序员在上机实习时,对C#上手很快,几乎没有遇到什么麻烦,而且竟然能用其进行开发,效率也高。我十分惊讶!

ROBERT HESS: 您觉得这些语言的哪些功能比C和C++表现得更出色?而您就可在新的语言中引进这些功能?

JEFFREY RICHTER:是的,有点。

ROBERT HESS:其中的原因是由于在C#中,您使用name.name.name.name,而不是name、->、name.name、-> name.*、*、()、&等老掉牙的东西……

ANDERS HEJLSBERG: 嗯,我认为有一件事可以说明,我总是喜欢Smalltalk,就是因为在该语言中,任何东西都是对象。这使程序得到了大大的简化,因为无论拥有什么样的数据片,都可以把它当作一个对象从A点搬到B点。一般来说,任何东西都可以对其进行操作。可以把它当作对象类型,放在容器中。在Smalltalk实际的实现过程中,如果这样做的话,程序性能的额外负担(overhead)就会大大加重。例如,在Smalltalk中,当运算float数字时,每生成一个新的数字,如当1.0和2.0加到一起时,就要分配一个含有3.0值的新对象。而这样做,代价当然是非常昂贵的。如今在C#中,我们已经进行了一些革新工作,使你获得了同一样的利益,而却没有额外负担。只要把float当成float,或者是double就把它当成double使用,就没有什么代价。但如果把它们视为对象(也仅当这样做时),就得给它们分配堆(heap)。因此,就形成了样相当完美的统一体,既能给您大量的好处,而又没有程序性能的额外负担。

ROBERT HESS:那么,对于观众中跃跃欲试的开发人员,他们想要投身于C#,并要开始编写一些.NET应用程序,在他们跨出第一步之前,需要真正地了解什么?您认为最后还有什么要强调的?

JEFFREY RICHTER: 确实这样。

ROBERT HESS:C#生成的最终结果的某些结构到底如何?您得到了一个C#程序的文本文件并且编译它,那么编译器本身存在着些什么问题,如何设计这些方案以便在使用时更具效率,而这种优化其它语言有可能已经做过,而甚至最终还要生成二进可执行文件吗?

JEFFREY RICHTER:我认为,这些开发人员即将面临的一个最大问题就是,他们必须认识到是C#语言揭示了runtime和基类库中的性能,或许假以时日他们会从经验中学到。而许多人将会关注C#,也可能他们会试一试,或关注其它的.NET语言,也有可能会企图做一些不被这些语言所支持的事,接着当然认为这是不可能的。例如:在C#中,所有的数组默认都是基于0的,是以0索引(下标)开始的。但是公共语言运行库支持数组有任何的下边界和上边界。在基类库中构造了一个数组,它具有所设定的上下边界。但是C#自然不提供这些功能。因此,您必须去学习,随着时间的推移,就会了解它是什么,很多时候您或许可以使用其它语言,或者去访问语言的底层系统,语言是位于runtime顶端的,由于某些原因,设计者不让我们去访问底层系统。

ROBERT HESS:这些在VB中都不会用到。

ANDERS HEJLSBERG:嗯,我们已经做了一些涉及到如何编码的工作。假如你是一个C++程序员,当然熟悉怎么做,在C++中声明和实现是分开的。所以所有声明都放在H文件里,接着在另一些模块中把它包含进去(# include),然后再在CPP文件中写出实现程序。在C#中,把它们都写在同一个地方。这样,可在那里写出声明接着又立即写出实现代码。

ROBERT HESS:似乎就是这样,通过理解runtime底层的所有性能,然后您就可以把这些性能映射(map)给您目前正在使用的任何语言,以便了解它们是否提供给您所需要的功能。例如,我写网页时总是用纯粹的HTML编写,因为我知道它的具体功能是什么。但是假如我必须用FrontPage写,我知道FrontPage有它自己的格式(mindset),关系到网页的显示,并且我知道它能给我提供什么,不能提供什么。偶尔我也不得不转回纯粹的HTML并按这种方式增加某些东西或其它工具,这似乎是同样的事情。

JEFFREY RICHTER:正确。

ROBERT HESS:假如您必须在另外一些文件中采用在main文件中声明的某些值,那又怎么办?

JEFFREY RICHTER:有时在C#中也有这些功能,但却以不同的名字出现,例如,在公式语言库中,虚拟函数被称为family 。于是要在C#中创建一个虚拟函数,就会用protected 限定。对,或不用protected,但是在C#中的protected是等价于公共语言运行库中的family的。噢,搞混了。看看,连我自己也糊涂了。

ROBERT HESS:所以格式看来相当一致。

ANDERS HEJLSBERG:那么会出现什么情况呢?当编译时,实际生成的代码或重新生成的输出文件都含有两种代码:元数据(metadata),符号表(symbol tables)或其它相关的符号信息(symbolic information),而不是仅生成只含有可执行代码的X86机器码。在某种意义上,这些代码变成了自我描述。所以当想从一个代码片使用另一代码片时,只要引用它们便可,而这些代码的自我描述足以让人们知道在那里有什么类,类拥有什么成员,可以调用什么方法,属性是什么以及类型名是什么,等等。

ROBERT HESS:因此基本的思路听起来好象就是要去理解您正在使用的工具,以及它们在.NET framework底层的运行情况。好了,非常感谢Jeffery,又与您交谈我感到非常荣幸,以后我会找一个时间再次邀请您回来参加这个“show”节目的。

JEFFREY RICHTER:对,相当一致。当然,他们用大括号{}而不是begin和end,这可能使有些人不适应。但我认为,他们最多花不到5分钟的时间就可以克服它,而且更多产。

ROBERT HESS:那么,是不是象您所指的.OBJ文件或.EXE文件,抑或……

JEFFREY RICHTER:好,我很乐意,谢谢。

RROBERT HESS:那么以一个公司的立场,假如一个公司聘请您去开设一个C#培训班,因此我得去发现他们是否开始考虑把公司的一些成果移植到C#,这就是您建议他们要做的事吗?或者您认为他们应处于哪一个阶段?

ANDERS HEJLSBERG:嗯,您说的很对,我们在.NET中使用的格式就是PE格式,故可以指向另外的EXE或DLL。我们现在调用这些汇编程序,并基本上用这种语言大量地描述这些高级DLL,它们不仅含有代码,也含有这样的信息:说明什么在代码中,以及这些代码真正地引用了其它什么样的汇编程序。

ROBERT HESS:这就是程序员Jeffery对C#和.NET framework的看法。他提供给你们一些好资料,以让你们了解更新的开发领域。他讲到了很多的URL地址和源代码例子以及类似的资料。我保证把它们放在本记录稿的后面,所以请继续观看其余的“show”节目,看看还有什么内容。
……(略去与C#无关的谈话)

JEFFREY RICHTER:嗯,当然它取决于,首先他们必须决定是否要采用.NET framework作为开发平台。我认为这非常有价值,对于我来说毫无问题,那是我真正向往的平台。如果您正在开发.NET framework的应用软件,正在编写新的代码,在我看来会不费吹灰之力。 C#上手实在是很容易,它是一种生机勃勃的语言,使用正确的方法您会非常多产的。我个人也相信大量的VB程序员,VB6.0程序员,将会转向C#而不是VB7.0。

ROBERT HESS:您所说的代码是指二进制代码或可执行代码。

结束语

ROBERT HESS:那为什么?

ANDERS HEJLSBERG:嗯,实际上,我们并不直接生成可执行的X86机器码,而是生成MSIL,也就是中间语言,它由.NET定义,并由JIT(实时编译器)编译。

ROBERT HESS:谢谢您参加另一期的MSDN Show。这一次我们讨论了用C#编程的问题。

JEFFREY RICHTER:因为我认为C#揭示了公共语言运行库(common language runtime)之中的更多的特性,使您对代码及其所表达的方法具有更多一点的控制权。您将更直接地与runtime对话,runtime赋予了您更多的权力。

ROBERT HESS: Ok,这样看来,您拥有了一个可执行文件,其本身与中间语言以及元数据相关联,而如果我想要在其中一个应用程序里使用它,我只要指向它并说道,嘿,我要借用这些类,借用这些对象,并在这样的程序中使用它。这使我想起了许多人曾经提过的一个问题,涉及到中间语言存在着潜在的漏洞,有些人可能会攫取这种文件并对其进行反编译,然后再恢复成当初的源代码。因此,并非所有的智能特性(intellectual property)都有利于开发者。这方面还有什么问题?

ERICA WIECHERS:在下一期的MSDN Show节目里,我们将谈论SOAP以及它是如何被整合到.NET编程体系的。

ROBERT HESS:当然,我们本身谁都不是VB程序员,所以将明确地在C基础之上发展。

ANDERS HEJLSBERG:嗯,首先,您现在实际上可以用DLL进行处理。这可能有点难,但您可以采用包含X86码的一个DLL,然后至少把它反编译成汇编程序。您可做同样的……

ROBERT HESS: 到那时,我们再在网上见面。

JEFFREY RICHTER: 您是对的。

ROBERT HESS:在我的Apple II上,我一直都是这样做的。

更多资料的链接

ROBERT HESS:所以这正是它物有所值之处,我们有点偏离正题了。那么作为一种语言,您喜欢C#的哪些方面呢?是更简单、更彻底(clean)的编程吗?

ANDERS HEJLSBERG: 确实如此,我对此感到惭愧。但是运用.NET DLL并把其反编译成MSIL,也可以做相同的工作。它们并不能直接地被反编译成C#,尽管您也有可能蒙对,但太难了。不同的地方在于,有着非常多的符号信息(symbolic information)关联到由C#生成的代码,以及MSIL,对不起,是.NET汇编程序。例如,你可以从代码中得知,什么类在这里,它们的成员是什么,等等。这是一个需要解决的棘手问题,因为让代码自我描述(self describing)的好处多多,但事实上代码对自己进行的描述,也同样使反编译工具所处理的代码变得似乎容易理解了。如果我们认识到这个问题,基本上我们要做的,就是创建一个称作搅拌机(obfuscator)的东西,它会加入并搞乱代码,使代码变得几乎难于看懂,可仍然保留着原来相同的公共接口。

Microsoft C#资料:
C#综述和介绍(Overview and Introduction to C#,

JEFFREY RICHTER: 嗯,主要是去掉了无用的东西。 譬如, 嗯, C#不允许您把参数作为常量(const)声明,并且您不能拥有一个const的实体方法,而在C++中则可以。我知道某些人会认为那样会真的丧失语言的特性,但事实在C++中,const总是会被无情地抛弃,这样您就能在自己的代码中为所欲为了。由于C#实在是不允许您使用const,所以它又彻底又易于理解。现在,我想我应该说:对于我,.NET frameworks真正有趣的东西就是公共语言运行库。它定义对象如何运转,或如何创建类型,以及是什么定义了这些类型的行为。这样您就拥有了一个基类库,当然它是一个巨大的类库,它让您有权使用大量的东西,所以即使您愿意,也不必再三重写每一样东西了。您选择语言是您个人的事情,而我选择了C#是由于它是真正优秀的高阶语言,它让我能与framework对话。但在某种程度上,运用.NET runtime和基类库真正最佳的语言应该是中间语言(immediate language)汇编语言。

ROBERT HESS:是的,因为您遇到这样的难题:当采用、编写这些编译器程序时,就想让编译器理解代码(或类似的过程等),但却不想让人们在同一层次上看懂它们。

C#语言规范(C# Language Specification,

ROBERT HESS:哈!谈到汇编语言啦?

ANDERS HEJLSBERG:确实如此,确实如此。我确实想指出,对于一个小程序,实际上可以对其进行反编译,给出足够的时间和资源,你甚至可理解它在干什么。然而对于真实世界中的一个应用程序,这却是一项艰巨的任务。在现实中你最好运行这个应用程序,理解它在干什么,然后写出它的一个copy。你会很快达到这个水平的。

MSDN之声:深入C#专栏(MSDN Voices: Deep C# column,
    一个定期的专栏,在这里Bobby Schmidt分享他使用C#的观点和见识。

JEFFREY RICHTER:是的,谈到汇编语言了。我的意思是,它使您完全有权访问平台的底层,但在汇编语言的环境中效率会很低,有这么多的程序您必须一行一行地写。所以,C#语言高出了一个层次。而在C#中的有些性能并不是很常用,因此象Anders 这样的C#设计者已决定不必将其公开了。在某些情况下,为了访问C#没有提供的runtime功能,我可能会求助于另外一种语言。但总的来说,C#是最高层的语言,它允许我在这样的环境中按自己的需求解决大量的问题,而且效率极高。

ROBERT HESS:或许写出一个更牛的程序,因为您是一个更牛的程序员,对吗?为了断定我们的观众是否想要着手实现下一个C#项目,他们需要去理解有关C#的一些什么问题?

MSDN .NET开发者中心(MSDN Developer Center for .NET,
     提供更多有关.NET技术的开发资料。

ROBERT HESS:并不是所有的问题,而仅仅只是大部份?

ANDERS HEJLSBERG:嗯,我想首先你必须考虑到自己的基础。如果你有现成的代码体,让我们假定它是用C++写成的吧,也许把这些代码移植到.NET framework的最佳途径就是使用Managed C++,该C++编译器随.NET一起发布。然而,如果你着眼于编写新的代码,也就是写新模块、更大的模块,加入到一个应用程序或一个完全了解的应用程序中,而且你精通C++,那么我建议考虑C#。

C#新闻组(C# Newsgroup,news://msnews.microsoft.com/microsoft.public.dotnet.languages.csharp)
与正在学习使用C#的人互相讨论、互相请教。

JEFFREY RICHTER:不,极少会出现这种情况:我还需要访问某些东西,而C#却不让访问。这是另外一方面,我只是认为大家非常容易忘却的是,当您想要访问.NET的一些功能而C#或某些语言却不提供给您时,可以转到别的语言。只需编码创建这个方法,可能是一个静态方法(static method),类中的静态方法,用APL或COBOL或凡是您选择的语言,或许派生,然后用某些语言实现实体方法,而这种语言可能真的让您访问某些底层功能。因此,我认为这是一个功能非常强大的范例,以前我从未真正地领会过要选择最佳的语言去完成工作。

ROBERT HESS:因此,我们没有必要说,每个人都必须用C#重写他们的应用程序。我们在说,人们必须了解他们目前所从事的工程的类型,是否是一个现成的项目、陈旧代码,并且有时还要用C#写一些组件,莫非您可以交替地使用C#和C++?

有关Jeffrey Richter谈话的资料:
代码范例(Sample Code:地址不详)
书: Programming Applications for Microsoft Windows
     Programming Server-Side Applications for Windows
(和Jason Clark合写)
Wintellect(
Jeffrey 的培训和咨询公司。
TerraServer.NET(
Jeffrey帮助编写的mapping服务。
Jeffrey Richter的主页(

ROBERT HESS:好了,我打赌各位观众可能想要看一些C#代码的例子,以便能理解我们谈论到的一些问题。您有例子示范给我们看吗?

ANDERS HEJLSBERG:噢,绝对。首先,如果你拥有现成的代码,假定这些代码是由Windows平台所支持的任何一种语言写成的,则把它们编译成COM组件或DLL,就会获得与这些代码很强的交互操作能力(interoperability)。如果要写专门用于.NET framework的代码,用于.NET framework的新代码,当然要用.NET framework所支持的任何语言写。我们计划在Visual Studio .NET中发布四种语言:C#、 C++、 Visual Basic 和 Jscript。可是为了与产业界和学术界合作,我认为,最新的统计可能不是很准确,但我想总共大约17种不同的语言现在都瞄向了这一个平台,其范围一直从APL到Cobol。

JEFFREY RICHTER:有。我确实的带来了一个源代码文件,里面有一些例子,能勉勉强强地应付,在节目结束后,我会给您的。欢迎您把它上传到网站上,以让大家可以下载。所以在这里,如果你样喜欢的话,我首先要示范的是:在C#中,每一个方法必须位于类中。没有全局方法,也没有位于类之外的变量,所以每一样东西都会被限定在一定的范围内。
using System;

ROBERT HESS:那么象Fortran又怎么样呢?

class App {
   public static void Main() {
      Console.WriteLine("Hello World",',',');
   }
}
这是一个必须保留的hello world程序,非常简单。在程序里,有一个类叫App,在这个类里,我拥有自己的一个Main方法,并且Main是一个静态方法,因为它必须从外面调用。我们不必拥有App的一个实例就可以调用Main。在我这个例子里,Main返回void,并且没有接受参数。简单地在Main的内部,它调用了Console.WriteLine,在显示器上面显示出"Hello World"。所以这是您可以写的、能学到相关概念的最小程序了。

ANDERS HEJLSBERG:我相信相关的工作正在进行中,可我不能准确地知道到底谁正在设计Fortran编译器。但关键的是,实际上我们已经做了多次示范了,你可以在C#中写一个基类,并在C++中继承它,然后再用VB程序创建它的一个实体。在不同的语言之间进行的互用操作是无缝的。我想正是这些性能,使.NET framework甩开产业界中其它竞争对手的产品。(有兴趣的读者可以到 Fortran for .NET Technology Preview 1,译注)**

ROBERT HESS:在C#中Main仍然是一个保留的方法吗?就象在C++中?

ROBERT HESS:而且它采用并允许在基础层次上进行多语言的互用操作。

JEFFREY RICHTER: Main是默认的,它具有大写字母M,小写字母a-i-n ,因为C#是字母大小写敏感的语言,象C++ 而不象VB 和.NET 。所以当编译器编译代码时,将寻找一个叫做Main的静态方法,然后再使用它。然而有一个编译器的命令行,它可以覆盖掉Main并选取其中不同的一个。顺便说一下,事实上这是一门很有用的技巧。一些人把多个Main放到一个单个的应用程序里,以便进行组测试,当编译时,可以设置不同的开关执行不同的Main,以便测试特定的组件。

ANDERS HEJLSBERG:是的,很准确。不过是位于一个很高的层次。您可能会争辩:现在的语言可以进行互用操作,但只能位于很低的层次,例如,DLL的入口点、具有指针在其中的结构,等等。而我们正在谈论到更高的语义层次,是位于面向对象的层次,具有类和接口等等。

ROBERT HESS:绝妙的技巧。您也使用象argv、 argc这样的参数,默认地传递给Main函数吗?
using System;

class App {
   public static void Main(string[] args) {
      Console.WriteLine("Hello World",',',');
   }
}

JEFFREY RICHTER:是,随您的便。在这里,我将当场修改这些代码,也就是说,string是一个字符串数组,args 按我在幻灯片中播放的定义。顺便地,这个args是什么呢?是一个数据类型!它是一个指向字符串的指针,或者是一个指向字符串的引用。说到指针,您只见过带*号的,但args确实是一个指针。当Main被调用之前,启动代码早已解析命令行,并且创建一个字符串数组,接着把指针传入该数组。象对args.length类似的调用使我可以解决一些问题,该调用会返回数组的length属性,此属性含有数组元素的个数,然后我正好可以利用一个正常的for语句进行循环,或者可以用C#的for each,特殊的for each语句用于快速的循环。

ROBERT HESS:很新颖,这是在C或C++中所没有的。

JEFFREY RICHTER:正确。而我确实也有演示的代码,我找到了。
static void ArrayDemo() {
   // 声明一个指向数组的引用
   Int32[] ia; // 默认值为 null
   ia = new Int32[100];
   ia = new Int32[] { 1, 2, 3, 4, 5 };
   .
   .
   .
这是一个具有数组的代码的例子,所以我会略为提一下。在这个例子里,首先声明一个指向Int32s数组的引用,随意取一个"ia"用于整数数组。它只不过是一个指针,具有32位(bit)或64位值,如果它们仍在64位系统上运行,总是会被初始化为null,引用总是被初始化为null直到明确地设置它为止。下面一行,我随意new(构造)了一个有100个Int32值的数组。new返回一个引用,接着我把这个引用存到"ia"变量中。下一行只不过演示了另外一种构造的方式,这里我又new了一个Int32s数组,这种专门的C#句法以一个左大括号开始,后面跟着数组的元素,当然元素之间要用逗号分开,然后是一个右括号。当您第一次见到这种句法时,会觉得它有点笨拙。这只不过是new的另外一种用法,当然它可以推算出元素的个数。

ROBERT HESS: 而这只不过是预定义了值:
   .
   .
   .
   // 显示数组的内容
   foreach (Int32 x in ia)
      Console.Write("{0} ", x,',',');

   //使用多维数组
   StringBuilder[,] sa = new StringBuilder[10][5];
   for (int x = 0; x < 10; x++) {
      for (int y = 0; y < 5; y++) {
         sa[x][y] = new StringBuilder(10,',',');
      }
   }

   // 使用数组的数组(jagged arrays)
   Int32 numPolygons = 3;
   Point[][] polygons = new Point[numPolygons][];
   polygons[0] = new Point[3]  { ... };
   polygons[1] = new Point[5]  { ... };
   polygons[2] = new Point[10] { ... };
}

JEFFREY RICHTER:是的,很正确。这就是foreach,它出现在代码的第一行。"foreach"是C#句法,我肯定所有的.NET语言都会提供此句法,它是一个极其通用的编程典范,用这种方式,就可以遍历集合里的元素。因此,这里的foreach Int32 x中,"x"是一个变量,Int32当然是一种类型,接着我把引用赋予了数组。foreach将会自动推算出数组中有多少个元素,并且每当循环到Console.Write时,就会显示出元素的值,然后再移向下一个元素。

ROBERT HESS:而"for (i=0, i
JEFFREY RICHTER:对,精辟。尽管如此,我会给您一点提示,由于foreach有点酷,也十分精巧,因此省去了大量的编码。它也另外做一些有关类型转换(casting)的工作,这对您同样也有好处。所以一般来说,当我写一个循环时,我通常会以foreach开始,然后当我继续编码时,有时经常地,我随后认识到我需要一个迭代器(iterator),需要一个从0到实际数字的X。是的,我必须知道哪一个元素号。所以我终止了重写这个循环,相当频繁……

ROBERT HESS: 噢,真的吗?

JEFFREY RICHTER: 是真的。

本文由10bet手机官网发布于web前端,转载请注明出处:访谈录之C,创建Windows应用程序10bet手机官网:

上一篇:没有了 下一篇:委托和事件,委托的作用
猜你喜欢
热门排行
精彩图文