X x_coffee Unregistered / Unconfirmed GUEST, unregistred user! 2003-08-12 #25 以前我参加VC++培训的时候,有个老师就是看内存窗口来调试程序的,牛啊~
Y yfdciom Unregistered / Unconfirmed GUEST, unregistred user! 2003-08-12 #26 有什么可牛的,只要懂汇编就可以了 可惜我一定不会去学汇编的
R Randy_Mic Unregistered / Unconfirmed GUEST, unregistred user! 2003-08-13 #27 乎没用几分钟时间,Anders指着屏幕上的CPU窗口中的几个二进制位并且告诉 Chuck:“ 看!Chuck, 这个比特好像不应该在这儿,这是一个记录。”Chuck看了5秒钟并证实了Anders的意见。然后Anders看 着我并说:“利诺,在从网络安装期间,其中一个包由于某些原因向左偏离了一个字节,删除这个包并 重新安装。” --------------------------------- 我看到乐上帝~~~~~~~~~~~~~~~~~
乎没用几分钟时间,Anders指着屏幕上的CPU窗口中的几个二进制位并且告诉 Chuck:“ 看!Chuck, 这个比特好像不应该在这儿,这是一个记录。”Chuck看了5秒钟并证实了Anders的意见。然后Anders看 着我并说:“利诺,在从网络安装期间,其中一个包由于某些原因向左偏离了一个字节,删除这个包并 重新安装。” --------------------------------- 我看到乐上帝~~~~~~~~~~~~~~~~~
D DuckJoe_1 Unregistered / Unconfirmed GUEST, unregistred user! 2003-08-14 #29 强烈要求楼主———续————————————————[]
T takashiki Unregistered / Unconfirmed GUEST, unregistred user! 2003-08-15 #31 Bill Gates一定在他的操作系统中加入了这么一条指令: mov Microsoft,person ptr Anders
Z zhyesno Unregistered / Unconfirmed GUEST, unregistred user! 2003-09-10 #38 C#首席设计师Anders Hejlsberg专访 文章摘要:Anders Hejlsberg是微软.Net框架设计师、C#程序语言首席设计师。他所开发的Turbo Pascal和Delphi获得了极大的成功。他最新的C#[发音为"See sharp"]又为何物呢?假定.NET平台上支持多语言,那为什么选择C#而不是Visual Basic、C++甚至COBOL?是什么使C#如此引人注目?看看Anders Hejlsberg的说法吧. 作者:John Osborn 译者:荣 耀 [译序:精彩技术,不容错过!限于时间和能力,译文倘有讹误,当以英文原版为准。] 7月,O'Reilly 编辑John Osborn参加了微软职业开发者会议。在此,他对著名的工程师、微软.Net框架设计师、C#程序语言首席设计师Anders Hejlsberg进行了采访。Anders Hejlsberg因设计PC上最早的语言之一-Turbo Pascal而出名。他把Turbo Pascal授权给Borland公司,后又率队开发了Delphi-一个极为成功的可视化的客户/服务应用设计工具[译注:此处不必拿MIDAS之类较真J]。访问时在座的还有微软C#产品经理Tony Goodhew和O'Reilly的Windows编辑Ron Petrusha。 Osborn: 我已经看到一些关于C#[发音为"See sharp"]的新闻故事,我注意到有很多似乎倾向于这样的观点-或理论上说-C#不是Java的克隆就是Java的微软替代物。如果你来写这个标题,你希望人们怎么评论这门语言? Hejlsberg: 首先,C#不是Java的克隆。在设计C#期间,我们考察了很多种语言,如C++、Java、Modula 2、C、Smalltalk等。很多语言都有我们感兴趣的相同的核心思想,比如深度面向对象、简化对象等等。 C#和这些别的语言尤其是Java的关键不同点是它非常接近C++。在我们的设计中努力使然。C#从C++直接借用了大多数的操作符、关键字和声明。我们还保留了许多被Java抛弃的语言特性。为什么Java中没有枚举,道理何在?我的意思是,抛弃它们是基于何种理论基础?在C++中,枚举显然是一个很有意义的概念。在C#中,我们保留了枚举并同样使其类型安全。并且,枚举不只是整型,它们实际上是从.NET基类库里的System.Enum派生下来的强类型的值类型。如果没有造型转换,枚举类型"foo"和枚举类型"bar"不可互换。我认为这是个重要的差异。我们还保留了操作符重载和类型转换。C#名字空间的整体结构也非常接近C++。 但是,超越这些传统的语言论题,我们设计语言的一个关键的目标是使C#面向组件。我们向语言自身加入了你在编写组件时所需要的所有概念。例如属性[译注:即property,翻译为"属性",由来已久。我怀疑如果先有attribute的话,property会不会被翻译为"性质"、"特性",而attribute才是"属性":JL]、方法、事件、特性[译注:即attribute,截至目前,此名词译法仍较混乱。有的翻译和property不区分,也译为"属性";有的译为"特性";有的译为"属性信息"。在该名词译法尚未统一之前,本着精简原则,笔者先把它翻译成"特性"。但注意,XML中的attribute的译法一般比较统一,即为"属性"(因为XML中没有一个类似于property的东西会与之混淆)。 因此,本文最后交叉描述C#和XML的部分,请留心"特性"、"属性"各有所指。]和文档等,它们都是一流的语言结构。我们对特性所做的工作是全新的和创新的。利用特性可为任何对象加入有类型的、可扩展的元数据。这在目前任何其它程序语言里都看不到的。C#也是第一个合并XML注释标记的语言,编译器可以用其直接从源码中生成可读的文档。 另外一个重要的概念是我所说的"一站购物式软件"[one-stop-shopping software]。一旦你用C#写代码,你就在这一个地方写了一切。不再需要头文件、IDL(接口定义语言)文件、GUID和复杂的接口。因为它是自包容的单元。一旦用这种方式写自描述的代码,你就可以把你的软件嵌入到ASP页面或植入各种不同的环境,这在以前是不可能的。 但是让我们再回到组件这个重要的概念。语言是否应该支持属性或事件,业界有很多争论。没错,我们是可以用方法表达这种概念。我们可以用诸如"get"或"set"之类的程序块的命名模式模拟属性的行为。我们可以用接口和实现接口的适配器并转发到对象。这都是可能实现的,就象可能在C语言里进行面向对象编程一样。只是它太困难了,需要太多的手工劳动,为了表达你真正的思想,你最终不得不去做所有的工作。我们认为是时候了,应该有个语言使得创建组件变得容易些。今天程序员在创建软件组件。他们并不是创建整个应用或整个类库。每个人都是在创建从宿主环境提供的基组件继承下来的组件。这些组件重载一些方法和属性,它们处理一些事件,并把组件安装回系统。树立这些概念是关键的第一课。 Osborn: 你最近在介绍C#时,第一张幻灯片上面写着:"C/C++家族里第一个面向组件的语言"。 Hejlsberg: 是的。这是我的首要目标之一。我们谈论一切如何都是对象,这也非常关键。以前象Smalltalk和Lisp语言都可以这么做,但代价昂贵。我认为C#包含一些优美有趣的创新使得组件开发容易些。例如装箱和拆箱的概念。装箱可以使一个值类型的值转换为一个对象,拆箱可以使一个对象转换为一个简单类型的值。这在以前或许也有,但我们把它应用于语言的方式是一种优美的创新。 我们努力避免用"象牙塔"的方式设计C#和.Net框架。我们承受不起重写我们所有的软件的负担。业界也负担不起,特别是今天我们正转移到Internet时代。你要善于利用你已经拥有的。所以,我认为互操作性也是关键的。我们致力于为程序员提供所有符合Internet标准的可互操作的正确的解决方案,例如HTTP、HTML、XML以及微软已经存在的技术。所以你不会有如坠深渊的那一刻-发现新的.NET框架下没有提供你用的一些东西,或者你意识到你想利用一些已经存在的API或组件的时候。你已经看到我们已把所有COM的互操作能力内建入语言和公共运行时;你已经看到可以使用DllImport特性导入已存在的DLL[动态连接库];你已经看到即使那些都不能遂你愿,我们也有不安全代码的概念。不安全代码允许你写使用指针的内联C代码,可以做不安全的造型转换,可以抑制内存从而使其不会被意外地垃圾收集[译注:此处用作动词J]。 关于不安去代码有很多争论,人们似乎认为我们在吸毒或是在干什么别的坏事。我认为这是个误会。代码不会仅仅因为标记了"不安全"就表示它不受管制。当然,我们不会扔出不安全的指针使人们容易受到从Internet下载的不安全代码的攻击。不安全代码被深深地约束在安全的环境里。我们提供这样的弹性:1.呆在受管制的代码箱里完成工作而不会坠入深渊;2.转入一个不同的语言使用一个不同的编程模型写本地代码。如果你停留在这个箱子里,我们会使代码更加安全,因为系统知道它要干什么。事实上,即使你写不安全代码也不意味着你离开了受管制的空间。你的不安全代码会变得更有效率。 Osborn: 请给我多讲一些在受管制的环境里处理不安全代码的机制。 Hejlsberg: 好的。描述受管制的执行环境比如Smalltalk、Java和.NET公共语言运行时一个重要特征是它们提供垃圾收集机制。为了提供垃圾收集机制,至少要提供一个现代的垃圾收集器,一个"标记和清扫"垃圾收集器。比起传统不受管制代码来说,你必须更多地了解正在执行的代码。为了找出要排除的死对象,你必须能遍历堆栈,找到所有活动的根,并指出哪些对象是活动的哪些是不再被访问的。然而,为了能够达到这个目标,你必须和你执行的代码紧密协作。代码必须具有更好的描述性。它要告诉你它是怎么分布在堆栈里的,它的局部变量存放在何处等等。 当我们在C#中编写不安全代码时,你可以做不是类型安全的事,比如指针操作。标记为不安全的代码并非绝对执行在不可信任的环境里。为了使之执行,你必须授予信任,否则,代码将不会执行。从这一点来看,和其它本地代码并无区别-真正的区别是它们仍然运行在受管制的空间里。你写的方法有一个描述表,它告诉你哪些对象是活动的,因此,不管什么时候你进入这些代码,你都不必穿越列集边界。否则,当你进入非描述性的、不受管制的代码(比如通过Java本地接口),你不得不在堆栈上设置一个水印或设置一个屏障。你必须重新列集所有箱子外的参数。一旦开始使用对象,你必须对你触及的东西小心翼翼,因为GC[垃圾收集器]仍然在另一个不同线程里运行。如果你不使用一些隐晦的方法锁定对象从而正确地抑制垃圾收集器,它可能会移去对象。如果你忘记那么做,那你将会不走运。 我们采用了一个不同的方式。我们说过,"让我们集成这个到语言中去。让我们提供声明,例如fixed声明,它可以让你抑制对象以和GC协作并集成之。"用这种方法,我们提供最佳方式,带领所有已经存在的代码一起向前,而不是仅仅将它们抛弃。这是一个不一样的设计方式。 Osborn: 因此,你们对不安全代码的处理方式是-不安全代码的内存实际上是在垃圾收集器的监视之下? Hejlsberg: 是的。但是,就象所谓的"购者自慎,不包退换"一样,它并不安全。你可以获取指针并做错事-当然,你在本地代码里也能干同样的错事。 Osborn: 我认为另一个易混淆的地方,是理解C#在哪儿停止和公共运行时从哪儿开始。与它从公共运行时库得到的相比,C#语言自身的创新是什么? Hejlsberg: 好的,我想这个混淆来源于这样一个事实-当人们谈论Java时,他们并不真的知道哪个是语言哪个是运行时。当人们谈论Java时,混淆就发生了。哪个语言哪个是运行时?当他们谈论Java时,他们到底指的是什么?Java,语言?Java,语法?还是Java,平台?人们把这些不同的方面混成一团。我们的方式表明我们想成为一个跨语言的平台。我们将创建一个平台,它允许你进行多语言编程,并且共享一套公共的API(应用编程接口)。让我们承认这一点,一些人喜欢用COBOL编程,一些人喜欢用Basic编程,一些人喜欢用C++,还有一些人将会喜欢用C#-我希望。但是,我们不会试图告诉你,忘记你曾经做过的所有的事情吧,我们不会说,"现在只有一种语言,在这个竞争中不会再有创新了"。我们说业界因为弹性而友好。Java是怎么来的?它的出现是因为在它前已经存在一些编程语言,而在它后也还将会出现一些编程语言。我们想打造一个平台,在此你可以偏爱某种语言但不会否定整个价值取向;我们想打造一个平台,它将是创新的。今天谁在帮助COBOL程序员?谁把他们带入WEB?只有在.NET平台上你才可以把富士通COBOL嵌入ASP页面。我的意思是,它真正是革命性的! Osborn: 假定.NET平台上支持多语言,那为什么选择C#而不是Visual Basic、C++甚至COBOL?是什么使C#如此引人注目? Hejlsberg: 首先,C#可以使我们从一张白纸开始。也就是说,我们没有任何向后兼容性的负担。这显然会使事情简化,无论从是从实现的立场还是从使用的立场都是这样。例如,在C#中,我们只有一类类型,并且总是被垃圾收集。而另一方面,受管制的C++有两套。因为它要保留非垃圾收集风格的编程。因此,在C#中,只需要你理解一些简单的概念。 语言是一个有趣的东西,它是一种口味;语言又是一件严肃的事情,它是程序员选择的一种生活方式。我是指,我们意识到我们不能走出来说,"这儿有个平台,你只可以使用一个基础语言。"即使在那个平台上用一种语言可以做所有的事情,人们还是可能不喜欢它的语法。他们可能喜欢大括号或者一些其它的程序块分界符。那是他们熟悉的。那是使他们感觉舒服并且富有生产力和能力的。我们对待C#的方式仅仅是为认为语言太复杂的C++程序员和认为丢失了一些C和C++语言特性的Java程序员提供一个可选物。我们寻求一个简化C++的方式并投入到一个多语言的平台中,它提供更大的互操作性,并且它提供完备的组件概念等等。 Goodhew: 一件有趣的事情来自于我们对开发者跟踪调查,60%以上的职业开发人员使用两种或更多的语言去创建他们的应用。特别是当我们问他们都用哪些开发工具的时候,我们得到的答案是:没有哪一种开发语言将会是终结者并且所有程序员都会使用它。正如Anders早先所说,人们期望某种能够满足他们所做或他们所感的语法。这是一个个人选择。这也是整个.NET平台所关心的-提供给开发者一个语言实现选择。我想我们做了件漂亮的工作。你基本上可以在Visual Basic、.NET和C#中做同样的事情。Visual Basic对大多数程序员来说仍然是易接受的。C#则具有更多的活动空间并且比VB更富威力。 Osborn: 这意味着在C#中可用更少的声明实现更多? Hejlsberg: 是的。意味着通过不安全代码,你可以得到更多的能力。 Osborn: 也就是说,不能在VB中写不安全代码? Hejlsberg: 是的。不可以。 Goodhew: 但是,基本上,两种语言都可以做同样的事。和Visual Studio 6相比,这是一个根本性的改变。在Visual studio 6.0中,如果你想创建多线程的MTS对象,并且你是一个VB程序员,你就没招。你不得不用C++。现在,有了.NET框架,你可以使用任何一种你喜欢的语言。 Hejlsberg: 这就是我在一般会议谈话里说过的,.NET框架提供一致的编程模型。在语言和框架的进化过程中,我们一贯似乎都是把一种程序语言绑死在特定的API和特定的编程方式上。VB是快速应用开发工具;MFC(微软基础类)是子类化的方式;ASP则是把东西塞到Web页面中。在每一种情况下,你对编程模型的选择决定了你对程序语言和可使用的API的选择。每次当你变换框架时,它都增加了你学习新语言和API负担的工作量。我们真正努力统一这一切,我们提供一套API,一套支持可视化设计的工具,我们还提供一个可以任选一种适合你的语言的弹性。 Osborn: 我不知道这对那些使用象VBScript和Jscript脚本语言的有什么作用? Hejlsberg: .NET框架下奇妙的事情之一是使脚本语言能够编译。看看ASP+,现在,实际上,在你的页面里运行的是真正编译的代码。它不是后绑定的、调度查找的-如果用户没有点击页面,你不会看到运行时错误。ASP+开发者可以使用Visual Basi.NET完整的威力而不是VBScript。并且第一次,他们可以使用Perl、Python和其它流行语言,如果他们这么选择的话。 Petrusha: 服务端的JavaScript现在也能被编译? Hejlsberg: 没错。 Goodhew: .NET框架使得使用脚本语言就象用具有完全特性的语言一样,因为它们现在访问的是一个真正的编程框架并且访问的是同一基类API。你应该看看搞Jscript实现的伙计们都已经实现了什么。[编注:Jscript是微软对ECMA 262语言规范(ECMAScript 版本 3)的实现,只有一些很小的例外(为了保持向后的兼容性),Jscript是对ECMA标准的完整实现]。所以.NET平台提供了一个公共语言框架,对脚本写作者来说,具有极大的好处。 Osborn: 我们已经讨论关于Java、C++和脚本。在PDC[译注:(微软)职业开发者会议],我听很多人争论.NET IL(IL是微软中间语言,所有编译器都必须产生它以运行在.NET框架上)和运行于Java虚拟机中的Java字节码并没有什么不同。从你的谈话中,显然你并不同意这一点。你介意进一步评论它们之间的区别吗? Hejlsberg: 好的。首先,IL的思想是一个很老的思想了。你可以追溯这个概念到UCSD Pascal p-machine(一个早期的个人计算机Pascal实现)或者Smalltalk。P-code曾被Basic和Visual Basic使用,Word的一个组成部件,内部使用p-code引擎,因为它更精简。所以,p-code并不是什么新东西。 我认为,我认为我们使用的IL的方式对此感兴趣:我们给你一个选择-如果你愿意-你可以控制把IL编译或翻译为本地代码的时机。实际上,使用受管制的 C++,你可以直接从源程序生成本地代码。受管制的 C++还可以生成IL,就象C#和VB那样。当你安装你的代码时,我们给你一个编译选项,可把IL编译成本地代码。因此,当你运行它们时,就不会有即时编译负担。我们还给你提供了一个动态运行和编译代码的选项-即时编译。有了IL,就给你带来了很多便利,比如它提供了这些能力:移植到不同的CPU结构并引入真正的类型安全并在此之上创建安全的系统。 我认为我们IL的设计和Java字节码关键的不同在于,我们做出了超前的决定-不用解释器。我们的代码永远本地运行。因此,即使产生IL,你也不会运行解释器。我们还有不同风格的JIT。对于精简框架,我们有EconnoJIT,就象我们称呼它的一样,它是一个非常简单的JIT[编注:精简.NET是.NET框架的一个子集,是为移植到其它设备和平台设计的]。对于桌面版,我们有完全功能的JIT。我们甚至有可和我们的C++编译器共用一个后端的JIT。不过,这都会比较耗时,因此你只应该在安装时使用它们。 一旦你做出偏向于执行本地代码而不是解释码的决定,它就会深深地影响IL设计。它改变了应该包括那些指令,应该包括哪些类型信息,以及它应该如何传输。如果你仔细看看两个IL[译注:即.NET IL和Java字节码],你就会发现它们非常不同。从某种意义上讲,我们的IL是类型中立的。指令里没有指定参数类型的信息。进一步说,它是靠已经压栈的东西推断出来的。这种方式使IL更为精简。无论如何,一个JIT编译器需要知道哪些信息,因此没有理由在指令里携带它们。所以,最终我们做出了不同的设计决定,而这使得容易把IL翻译成本地代码。 Osborn: 解释方式和你描述的方式有何不同? Hejlsberg: 解释器的核心是一个循环-从p-code流取得一些字节,然后进入一个大大的switch[译注:类似于程序语言里的switch...case]声明:"哦,这是ADD指令,因此它到这儿来,但是这不是…"等等。 解释器模拟CPU。我们反其道而行之,我们只走一条道,我们一直都走一条道,我们把指令翻译为机器码。现在,在EconoJIT的情况下,机器码实际上非常简单,它只创建一个调用和压栈指令的列表,并且调用运行时帮助器,然后运行时帮助器替换这个列表。当然,这个代码比解释器代码执行得快。 Osborn: 让我用一句话来总结一下:你们完全编译代码。因此当你编译完时,字节已经完全准备好运行了,尽管从IL翻译成机器码的时机可能不同。 Hejlsberg: 是的。但是,如果它是在一个内存受限的小设备的环境里,有可能当运行完就被扔掉了。 Osborn: 让我们进入语法细节。我在想,C#是否包括对正则表达式的内建支持。我没有在语言参考里看到它,或许它可能在别的什么地方吧。 Hejlsberg: 首先,在基类库里有一个正则表达式类。我们并没有在语言里加入对正则表达式的任何直接支持,但是,实际上我们有些非常类似的特性。并不值得对它们做重大的处理。但是,比如当你需要指定一个时候-我们给你这个能力去写一个逐字字符串而不需要你每次写两个后斜杠。当你写正则表达式时并且当你的正则表达式里的引号还套引号时,它实际上有极大的帮助。虽然这个帮助不足挂齿,但显然其核心在.NET框架里,而这个框架可以被任何编程语言共享。 Osborn: C#和Java名字空间看起来不同。它们是否概念相同而实现上不同? Hejlsberg: 概念上是的,但是在实现上非常不同。在Java里,包名也是物理的东西,它指定了你的源代码文件的目录结构。在C#中,物理包和逻辑名称完全独立,无论你如何称呼你的名字空间,它都和你的实际代码的物理包不相关。这就给你更多的弹性-把物理上分布的单元包装在一起,并且不强迫你建很多的目录。在语言自身,有很多很明显的区别。在Java里,包也是你的物理结构,因此,Java源文件必须在正确的路径里,并且只能包含一个公开类型或者一个公开的类。因为C#没有那种物理和逻辑上的绑定,所以你可以任意命名你的源文件。每一个源文件都可以被多个名字空间使用并且可以带有多个公开类。进一步讲,你可以把所有的源码写在一个大文件里,或你可以把它们分散到交叉的小文件中去。概念上讲,C#编译时发生了什么-你给编译器提供了所有构成你的工程的源文件,然后它只管前进并指出该干什么。 Osborn: 我有一个关于泛型编程的问题:你认为它是个重要的概念吗?它应该成为面向对象语言的一部分吗?如果是的话,你们把泛型编程加为C#的一部分的计划如何? Goodhew: 好的。在第一个版本里包括泛型编程的愿望受到了限制。并不象每一个人以为的那样,微软并没有无限制的资源。在这第一个版本里,我们不得不做一些困难的决定。 Osborn: 有多少人参与开发C#? Hejlsberg: 语言设计组由4个人构成,编译器组由另外五个开发人员构成。 Petrusha: 框架呢? Hejlsberg: 那就多了,整个公司都被卷入了。 Goodhew: 就整个Visual Studio和.NET平台组而言,我们的部门大概有千人左右。包括程序管理人员、开发人员、测试人员,包括所有创建例程、框架、运行时、ASP编程模型的人员以及其它所有的人比如我,管理层的。 Hejlsberg: 就你刚才所说的泛型方面,我明确地认为它是个非常有用的概念,并且你当然可以列举出发生在学术界和业界所有的泛型研究。模板是该问题的一个解决方法。在我们内部讨论中,我们决定要在新平台里做这个事情。但我们真正喜欢做的是让底层的运行时理解泛型。这和如何创建泛型原型是不同的。用Java的"擦除"概念系统里没有真正的泛型知识。如果公共语言运行时理解泛型的概念,多种语言就可以共享这个功能。你可以在一个地方用C#写一个泛型类,别的人用别的语言也可以使用。 使泛型成为运行时的一部分还可以使你更有效率的做某些事情。泛型初始化的最理想的时间是在运行时。如果用C++,模板的初始化发生在编译时,你有两个选择:听任你的代码膨胀或试图在链接时去除掉一些膨胀代码。但是,如果你有多个应用,你可能会忘记这一点,你将只能得到膨胀的代码。 如果把泛型的知识纳入公共语言运行时,则运行时可以理解-当一个应用或组件请求一个"Foo"列表时,它首先会问:"我已经有了一个初始化的"Foo"列表了吗?"如果是,就用那一个。实际上,如果Foo是一个引用类型,并且我们设计正确的话,我们可以让所有引用类型共享初始化。对于值类型,比如整型和浮点型,我们可以为每一个值类型创建一个初始化,但这应该在应用请求时才做。为了把泛型加入运行时,我们已经做了大量的设计工作和必要的基础性工作。 你先前提到的关于IL的东西是有意思的,因为加入泛型的决定影响了IL的设计。如果IL指令嵌入类型信息,如果,例如,一个"加"指令不再是个"加"了,而是一个整数"加"或是浮点数"加"或是一个双精度数"加",你就把类型信息硬加入到了指令流里,并且在这一点上来说IL不是泛型的。我们的IL格式实际上是真正的类型中立的。并且,为了保持类型中立,我们可以迟些时候加入泛型而不会给我们带来麻烦,至少不会太麻烦。这也是我们的IL和Java的字节码看起来不一样的原因之一。我们IL类型中立。"加"指令可以加栈顶的任何两个东西。在泛型世界,当它被初始化时,它可以被翻译成不同的代码。 Osborn: 所有.NET语言都可获得泛型能力吗? Hejlsberg: 是的。微软剑桥研究院已经创建了一个支持泛型能力的公共语言运行时和C#编译器的版本,我们正在研究如何尽快使其前进。第一个版本是不可能加入泛型了,我们知道的就这么多。但是我们正在工作以确保我们在第一个版本里做了正确的事情从而使泛型可以适用于整个蓝图。 Osborn: C#和.NET框架以及Visual Studio的下一个版本计划发行日期是? Goodhew: 唔,我们为来这儿参加PDC的6500名人员带来了技术预览版。我们希望2000年秋季的某个时间发布beta版,然后在准备好以后,我们发布发行版。我们所做的一个真正令人激动的事情是看看Windows2000发行版发布进行的如何,以让关键客户参与到合作开发和合作部署的进程中来。关于.NET框架和Visual Studio.NET,我们将再次和客户一起工作以决定最终产品的发行日期。我们打算让他们告诉我们什么时候产品该就绪了。并且,因为有真正的客户参与到这个进程中来,我们将获得更好的产品质量。这种做法的不利的一面是使产品开发和发布的进程有点不确定。但这是根本性的改变。我们在寻找一个打破质量障碍的产品发行方式,而不仅仅是挑一个武断的日期说我们要发货了。 Osborn: 因此,不是一个代码完成的日期,我们在寻找一个"准备好出发"的日期? Goodhew: 是的,没错。我认为开发者将会发现Visual Studio.Net发行版是微软历史里最高质量的发行版本之一。 Osborn: 你们已经把C#提交给ECMA[译注:欧洲计算机制造商协会]。标准化真的是一个严肃的目标吗?你希望在其它平台上也可使用C#吗? Hejlsberg: 的确如此!把C#作为一个可能的标准提供给业界当然是我们的目标,这也是我们把它提交给ECMA的原因之一。在引导这个有着公共语言基础设施的公共设计的语言的进程中,我们当然希望得到ECMA的支持。关于公共基础设施,我的意思是指这个规范所规定的一个核心类库集,如果其它公司使用其它平台实现它,他们有理由期望发现可以在他们的程序里利用这些类。 Goodhew: 我想指出的是我们正在和ECMA做真正的开放标准。当ECMA为C#和公共语言基础设施达成标准后,在ECMA的版权和授权政策下,真正的开放将可实现。任何客户、任何人都可以被授权ECMA C#标准,子集之,超集之,并且不必付版税。他们可以在任何平台和任何设备实现之。我们完全希望人们那么做。这和我们的竞争者根本不同。他们徘徊在标准之外,寻找某某人去为他们私有的语言贴上印花。 John: 我在早餐和午餐时听说:"如果微软没有把COM搞到基础设施中去,平台会多么具有可移植性?" Hejlsberg: 完全可能。COM并非C#和公共语言基础设施标准化之必须。根本不是。C#有一个完备丰富的类模型,而COM则是从另外一个视角看待应用的互操作性。但是,C#和公共运行时的核心中从未说过必须要有COM、 GUID、 HRESULT、 AddRef 或 Release等等。一个都没有。.NET 公共语言运行时彻底摒弃了COM,但它还是给了你巨大的COM互操作能力。鉴于先前所述,我仍然认为它将非常重要,但绝非不可或缺。 Goodhew: 我认为这些评论起因于我们公开的最初版本的语言规范。微软在某次会议上把它写进了规范。在那次会议上,我们认为按照微软平台来说这是非常重要的。结果,我们在规范里多次引用COM和DLL这样东西。DLL是如何在已给定平台上激活本地代码的更多的一般性问题中的一个特例。对于纳入标准化组织以及和象IBM的人(我们和他们一起制订SOAP规范)一起工作的一个好处是我们可以不做任何这样的提及,以防止在规范的未来版本里,把我们自己绑死或锁定在象COM框架这样的东西上。 就象Anders说的那样,COM互操作能力和COM支持对我们和已有的微软客户来说是极其重要的。我认为为了在.NET支持COM我们做了大量的工作。但是,业界的人们已经阅读了大量的我们对COM和DLL字眼引用的东西,他们由此推论.NET仅仅是为Windows平台设计的,这是完全错误的。 Hejlsberg: 并且,我认为就象COM的互操作能力对于微软和在微软平台上构建解决方案的客户很重要一样,C#和公共语言基础设施的标准化将允许在任何其它平台上选择实现这个语言以加入意义重大的互操作能力。 Osborn: 所以你们将不会坚持应该有个什么"纯C#"和"纯.NET"的实现? Hejlsberg: 什么叫"纯"?真正有多少"纯"Java应用存在?我冒险猜测一下,非常非常少。那就是我估计的数量。让我们承认这一点,人们希望能利用他们已存在的代码。不可能叫那些公司把什么东西都扔掉。 Goodhew: 你和Roger Sessions交流过吗?[编注:Roger Sessions是ObjectWatch公司的CEO,并且是《COM+ and the Battle for the Middle Tier》的作者] 。 Osborn: 没有。 Goodhew: Roger谈到了EJB规范的相关章节,那儿讲了卖方[vendor]许可扩展。毫不奇怪,卖方扩展包括诸如事务管理、安全、消息以及其它更多的方面,这在构建企业级系统中是相当重要的。在一篇文章[译注: http://www.objectwatch.com/issue_24.htm]里,Sessions粗略地列举了11个领域的机能,这是可容许的卖方规范实现。因此,如果你选择IBM Websphere作为你的EJB实现,你为你的EJB应用写的代码将不可避免地被锁定在Websphere。Java是100%纯和100%可移植的概念是不正确的。在IBM的开发者工作站点上,有一个伟大的专访[译注:http://www-106.ibm.com/developerworks/features/gosling/index.html]。James Gosling直接指出了这一点。他说,是的,整个"写一次到处运行"、"100%纯的东西"真是个愚蠢的想法,更多的是属于营销上东西。他说,实际上,"我们并不认为我们能够交付这一切,基本上,我们办不到"。这就是这个语言的发明者说的,不存在什么纯粹性和可移植性。 Osborn: 我们有没有遗漏一些没透露的C#的伟大的特性或创新,你愿意补充一下吗? Hejlsberg: 关于.NET框架,隐含地,也包括C#,我想提的一点是:它是构建分布式应用的手段。并非很久以前,我们创建两阶层的客户/服务应用,然后对象协议如CORBA、 IIOP、 RMI、和DCOM 接踵而至。这种类型的编程是EJB-(CORBA或RMI的底层实现[译注:DCOM除外])的基础。我们已经会构建这种强连接式的分布式系统,但它们不具备伸缩性。它们在WEB上不能够伸缩因为它们是有状态的,它们在服务端保持状态,你不能够转入另一台机器,把它插入并让相关东西复制自己。 当初,当我们坐下来着手设计.NET框架时,我们回头看了看Web上究竟发生了什么。它正在变成松散连接、非常分布式的世界。我们努力理解它对潜在的编程模型的影响。因此,我们从根本上假定分布式的应用是构建在松散连接、无状态风格的。依此,我们做出的设计可提供巨大的伸缩性。你只管扩展。你转入更多的框架并且把它们插入。一旦做出了这个根本性的假设,一切就随之改变。它改变了怎样设计你的根本服务,怎样设计你的消息,甚至是怎样设计你的用户界面。这是一个新的编程模型。我们已经选择了XML和SOAP作为使这个模型工作的方式。它们被深深地集成到.Net。并且这种集成对于我们在设计.NET框架时做出的每一个决策是如此核心,以至于它不是那种你只是进来蜻蜓点水地逛一逛就可以的东西。 Osborn: 你能指出一些对程序员来说明显特别的地方吗? Hejlsberg: 一个相当好的例子是XML是如何被集成到C#中的。C#中有特性[译注:即attribute,关于名词译法的说明,上文有描述]的概念,它允许你向类型和成员加入宣称性信息。就象你可以说某个成员是公有的或私有的一样,你可能还想说这个是事务的,或者这个假定是个Web service,或这个假定被以XML方式的序列化支持。因此,我们加入特性以提供一般性机制,但是我们在所有的Web service和XML基础设施中都用到了它。我们还给你用特性修饰类和字段的能力。在你的类中,你可以说"当这个类型变成XML时,它应该变成"this"标签名,并且属于"this"XML名字空间。"你将有能力指定一个字段变成一个元素,而另外一个变成属性[译注:此处指XML中的属性]。你还能够控制XML的模式[译注:即schema];在你的类声明的地方控制它,这样,所有附加的宣称性信息就都可以获得了。一旦以该方式正确地使用特性修饰你的C#代码,系统就可以简单把它转化成XML中一个指定的类,在线上传输,当它传回时,就可以在另一端重建该对象。这都是在一处定义完成的。它不象传统的定义文件或多种信息和命名模式。它就在那儿。当你在IDE中创建它们时,它就给了你完整的声明。我们还可以提供高级工具,让它帮你做这个事。 我知道我有点离题了,但是我们提供的这些基础设施的确令人兴奋。单单因为我们有这些特性,你就可以请求XML序列化基础设施或Web service基础设施把已给出的类翻译成XML。当你这么做了,我们实际上将为这个类配上XSD模式,并且我们将创建一个特别的解析器,它是从我们一般的XML解析器派生出来的(.NET基类的一部分),并且重载方法并加入逻辑,因此它是专门为那个模式服务的。所以,我们已经初始化好一个解析器,可以本地代码的速度解析XML。如果它不正确,我们将给你一个体面的出错信息,它可以精确地告诉你是什么出了问题。我们可以在代码缓存基础设施中缓存它,它将坐等直到下一次一个具有同样模式的类来临并将发生作用,"嘭!",我的意思是,难以置信,难以置信的生产能力!
C#首席设计师Anders Hejlsberg专访 文章摘要:Anders Hejlsberg是微软.Net框架设计师、C#程序语言首席设计师。他所开发的Turbo Pascal和Delphi获得了极大的成功。他最新的C#[发音为"See sharp"]又为何物呢?假定.NET平台上支持多语言,那为什么选择C#而不是Visual Basic、C++甚至COBOL?是什么使C#如此引人注目?看看Anders Hejlsberg的说法吧. 作者:John Osborn 译者:荣 耀 [译序:精彩技术,不容错过!限于时间和能力,译文倘有讹误,当以英文原版为准。] 7月,O'Reilly 编辑John Osborn参加了微软职业开发者会议。在此,他对著名的工程师、微软.Net框架设计师、C#程序语言首席设计师Anders Hejlsberg进行了采访。Anders Hejlsberg因设计PC上最早的语言之一-Turbo Pascal而出名。他把Turbo Pascal授权给Borland公司,后又率队开发了Delphi-一个极为成功的可视化的客户/服务应用设计工具[译注:此处不必拿MIDAS之类较真J]。访问时在座的还有微软C#产品经理Tony Goodhew和O'Reilly的Windows编辑Ron Petrusha。 Osborn: 我已经看到一些关于C#[发音为"See sharp"]的新闻故事,我注意到有很多似乎倾向于这样的观点-或理论上说-C#不是Java的克隆就是Java的微软替代物。如果你来写这个标题,你希望人们怎么评论这门语言? Hejlsberg: 首先,C#不是Java的克隆。在设计C#期间,我们考察了很多种语言,如C++、Java、Modula 2、C、Smalltalk等。很多语言都有我们感兴趣的相同的核心思想,比如深度面向对象、简化对象等等。 C#和这些别的语言尤其是Java的关键不同点是它非常接近C++。在我们的设计中努力使然。C#从C++直接借用了大多数的操作符、关键字和声明。我们还保留了许多被Java抛弃的语言特性。为什么Java中没有枚举,道理何在?我的意思是,抛弃它们是基于何种理论基础?在C++中,枚举显然是一个很有意义的概念。在C#中,我们保留了枚举并同样使其类型安全。并且,枚举不只是整型,它们实际上是从.NET基类库里的System.Enum派生下来的强类型的值类型。如果没有造型转换,枚举类型"foo"和枚举类型"bar"不可互换。我认为这是个重要的差异。我们还保留了操作符重载和类型转换。C#名字空间的整体结构也非常接近C++。 但是,超越这些传统的语言论题,我们设计语言的一个关键的目标是使C#面向组件。我们向语言自身加入了你在编写组件时所需要的所有概念。例如属性[译注:即property,翻译为"属性",由来已久。我怀疑如果先有attribute的话,property会不会被翻译为"性质"、"特性",而attribute才是"属性":JL]、方法、事件、特性[译注:即attribute,截至目前,此名词译法仍较混乱。有的翻译和property不区分,也译为"属性";有的译为"特性";有的译为"属性信息"。在该名词译法尚未统一之前,本着精简原则,笔者先把它翻译成"特性"。但注意,XML中的attribute的译法一般比较统一,即为"属性"(因为XML中没有一个类似于property的东西会与之混淆)。 因此,本文最后交叉描述C#和XML的部分,请留心"特性"、"属性"各有所指。]和文档等,它们都是一流的语言结构。我们对特性所做的工作是全新的和创新的。利用特性可为任何对象加入有类型的、可扩展的元数据。这在目前任何其它程序语言里都看不到的。C#也是第一个合并XML注释标记的语言,编译器可以用其直接从源码中生成可读的文档。 另外一个重要的概念是我所说的"一站购物式软件"[one-stop-shopping software]。一旦你用C#写代码,你就在这一个地方写了一切。不再需要头文件、IDL(接口定义语言)文件、GUID和复杂的接口。因为它是自包容的单元。一旦用这种方式写自描述的代码,你就可以把你的软件嵌入到ASP页面或植入各种不同的环境,这在以前是不可能的。 但是让我们再回到组件这个重要的概念。语言是否应该支持属性或事件,业界有很多争论。没错,我们是可以用方法表达这种概念。我们可以用诸如"get"或"set"之类的程序块的命名模式模拟属性的行为。我们可以用接口和实现接口的适配器并转发到对象。这都是可能实现的,就象可能在C语言里进行面向对象编程一样。只是它太困难了,需要太多的手工劳动,为了表达你真正的思想,你最终不得不去做所有的工作。我们认为是时候了,应该有个语言使得创建组件变得容易些。今天程序员在创建软件组件。他们并不是创建整个应用或整个类库。每个人都是在创建从宿主环境提供的基组件继承下来的组件。这些组件重载一些方法和属性,它们处理一些事件,并把组件安装回系统。树立这些概念是关键的第一课。 Osborn: 你最近在介绍C#时,第一张幻灯片上面写着:"C/C++家族里第一个面向组件的语言"。 Hejlsberg: 是的。这是我的首要目标之一。我们谈论一切如何都是对象,这也非常关键。以前象Smalltalk和Lisp语言都可以这么做,但代价昂贵。我认为C#包含一些优美有趣的创新使得组件开发容易些。例如装箱和拆箱的概念。装箱可以使一个值类型的值转换为一个对象,拆箱可以使一个对象转换为一个简单类型的值。这在以前或许也有,但我们把它应用于语言的方式是一种优美的创新。 我们努力避免用"象牙塔"的方式设计C#和.Net框架。我们承受不起重写我们所有的软件的负担。业界也负担不起,特别是今天我们正转移到Internet时代。你要善于利用你已经拥有的。所以,我认为互操作性也是关键的。我们致力于为程序员提供所有符合Internet标准的可互操作的正确的解决方案,例如HTTP、HTML、XML以及微软已经存在的技术。所以你不会有如坠深渊的那一刻-发现新的.NET框架下没有提供你用的一些东西,或者你意识到你想利用一些已经存在的API或组件的时候。你已经看到我们已把所有COM的互操作能力内建入语言和公共运行时;你已经看到可以使用DllImport特性导入已存在的DLL[动态连接库];你已经看到即使那些都不能遂你愿,我们也有不安全代码的概念。不安全代码允许你写使用指针的内联C代码,可以做不安全的造型转换,可以抑制内存从而使其不会被意外地垃圾收集[译注:此处用作动词J]。 关于不安去代码有很多争论,人们似乎认为我们在吸毒或是在干什么别的坏事。我认为这是个误会。代码不会仅仅因为标记了"不安全"就表示它不受管制。当然,我们不会扔出不安全的指针使人们容易受到从Internet下载的不安全代码的攻击。不安全代码被深深地约束在安全的环境里。我们提供这样的弹性:1.呆在受管制的代码箱里完成工作而不会坠入深渊;2.转入一个不同的语言使用一个不同的编程模型写本地代码。如果你停留在这个箱子里,我们会使代码更加安全,因为系统知道它要干什么。事实上,即使你写不安全代码也不意味着你离开了受管制的空间。你的不安全代码会变得更有效率。 Osborn: 请给我多讲一些在受管制的环境里处理不安全代码的机制。 Hejlsberg: 好的。描述受管制的执行环境比如Smalltalk、Java和.NET公共语言运行时一个重要特征是它们提供垃圾收集机制。为了提供垃圾收集机制,至少要提供一个现代的垃圾收集器,一个"标记和清扫"垃圾收集器。比起传统不受管制代码来说,你必须更多地了解正在执行的代码。为了找出要排除的死对象,你必须能遍历堆栈,找到所有活动的根,并指出哪些对象是活动的哪些是不再被访问的。然而,为了能够达到这个目标,你必须和你执行的代码紧密协作。代码必须具有更好的描述性。它要告诉你它是怎么分布在堆栈里的,它的局部变量存放在何处等等。 当我们在C#中编写不安全代码时,你可以做不是类型安全的事,比如指针操作。标记为不安全的代码并非绝对执行在不可信任的环境里。为了使之执行,你必须授予信任,否则,代码将不会执行。从这一点来看,和其它本地代码并无区别-真正的区别是它们仍然运行在受管制的空间里。你写的方法有一个描述表,它告诉你哪些对象是活动的,因此,不管什么时候你进入这些代码,你都不必穿越列集边界。否则,当你进入非描述性的、不受管制的代码(比如通过Java本地接口),你不得不在堆栈上设置一个水印或设置一个屏障。你必须重新列集所有箱子外的参数。一旦开始使用对象,你必须对你触及的东西小心翼翼,因为GC[垃圾收集器]仍然在另一个不同线程里运行。如果你不使用一些隐晦的方法锁定对象从而正确地抑制垃圾收集器,它可能会移去对象。如果你忘记那么做,那你将会不走运。 我们采用了一个不同的方式。我们说过,"让我们集成这个到语言中去。让我们提供声明,例如fixed声明,它可以让你抑制对象以和GC协作并集成之。"用这种方法,我们提供最佳方式,带领所有已经存在的代码一起向前,而不是仅仅将它们抛弃。这是一个不一样的设计方式。 Osborn: 因此,你们对不安全代码的处理方式是-不安全代码的内存实际上是在垃圾收集器的监视之下? Hejlsberg: 是的。但是,就象所谓的"购者自慎,不包退换"一样,它并不安全。你可以获取指针并做错事-当然,你在本地代码里也能干同样的错事。 Osborn: 我认为另一个易混淆的地方,是理解C#在哪儿停止和公共运行时从哪儿开始。与它从公共运行时库得到的相比,C#语言自身的创新是什么? Hejlsberg: 好的,我想这个混淆来源于这样一个事实-当人们谈论Java时,他们并不真的知道哪个是语言哪个是运行时。当人们谈论Java时,混淆就发生了。哪个语言哪个是运行时?当他们谈论Java时,他们到底指的是什么?Java,语言?Java,语法?还是Java,平台?人们把这些不同的方面混成一团。我们的方式表明我们想成为一个跨语言的平台。我们将创建一个平台,它允许你进行多语言编程,并且共享一套公共的API(应用编程接口)。让我们承认这一点,一些人喜欢用COBOL编程,一些人喜欢用Basic编程,一些人喜欢用C++,还有一些人将会喜欢用C#-我希望。但是,我们不会试图告诉你,忘记你曾经做过的所有的事情吧,我们不会说,"现在只有一种语言,在这个竞争中不会再有创新了"。我们说业界因为弹性而友好。Java是怎么来的?它的出现是因为在它前已经存在一些编程语言,而在它后也还将会出现一些编程语言。我们想打造一个平台,在此你可以偏爱某种语言但不会否定整个价值取向;我们想打造一个平台,它将是创新的。今天谁在帮助COBOL程序员?谁把他们带入WEB?只有在.NET平台上你才可以把富士通COBOL嵌入ASP页面。我的意思是,它真正是革命性的! Osborn: 假定.NET平台上支持多语言,那为什么选择C#而不是Visual Basic、C++甚至COBOL?是什么使C#如此引人注目? Hejlsberg: 首先,C#可以使我们从一张白纸开始。也就是说,我们没有任何向后兼容性的负担。这显然会使事情简化,无论从是从实现的立场还是从使用的立场都是这样。例如,在C#中,我们只有一类类型,并且总是被垃圾收集。而另一方面,受管制的C++有两套。因为它要保留非垃圾收集风格的编程。因此,在C#中,只需要你理解一些简单的概念。 语言是一个有趣的东西,它是一种口味;语言又是一件严肃的事情,它是程序员选择的一种生活方式。我是指,我们意识到我们不能走出来说,"这儿有个平台,你只可以使用一个基础语言。"即使在那个平台上用一种语言可以做所有的事情,人们还是可能不喜欢它的语法。他们可能喜欢大括号或者一些其它的程序块分界符。那是他们熟悉的。那是使他们感觉舒服并且富有生产力和能力的。我们对待C#的方式仅仅是为认为语言太复杂的C++程序员和认为丢失了一些C和C++语言特性的Java程序员提供一个可选物。我们寻求一个简化C++的方式并投入到一个多语言的平台中,它提供更大的互操作性,并且它提供完备的组件概念等等。 Goodhew: 一件有趣的事情来自于我们对开发者跟踪调查,60%以上的职业开发人员使用两种或更多的语言去创建他们的应用。特别是当我们问他们都用哪些开发工具的时候,我们得到的答案是:没有哪一种开发语言将会是终结者并且所有程序员都会使用它。正如Anders早先所说,人们期望某种能够满足他们所做或他们所感的语法。这是一个个人选择。这也是整个.NET平台所关心的-提供给开发者一个语言实现选择。我想我们做了件漂亮的工作。你基本上可以在Visual Basic、.NET和C#中做同样的事情。Visual Basic对大多数程序员来说仍然是易接受的。C#则具有更多的活动空间并且比VB更富威力。 Osborn: 这意味着在C#中可用更少的声明实现更多? Hejlsberg: 是的。意味着通过不安全代码,你可以得到更多的能力。 Osborn: 也就是说,不能在VB中写不安全代码? Hejlsberg: 是的。不可以。 Goodhew: 但是,基本上,两种语言都可以做同样的事。和Visual Studio 6相比,这是一个根本性的改变。在Visual studio 6.0中,如果你想创建多线程的MTS对象,并且你是一个VB程序员,你就没招。你不得不用C++。现在,有了.NET框架,你可以使用任何一种你喜欢的语言。 Hejlsberg: 这就是我在一般会议谈话里说过的,.NET框架提供一致的编程模型。在语言和框架的进化过程中,我们一贯似乎都是把一种程序语言绑死在特定的API和特定的编程方式上。VB是快速应用开发工具;MFC(微软基础类)是子类化的方式;ASP则是把东西塞到Web页面中。在每一种情况下,你对编程模型的选择决定了你对程序语言和可使用的API的选择。每次当你变换框架时,它都增加了你学习新语言和API负担的工作量。我们真正努力统一这一切,我们提供一套API,一套支持可视化设计的工具,我们还提供一个可以任选一种适合你的语言的弹性。 Osborn: 我不知道这对那些使用象VBScript和Jscript脚本语言的有什么作用? Hejlsberg: .NET框架下奇妙的事情之一是使脚本语言能够编译。看看ASP+,现在,实际上,在你的页面里运行的是真正编译的代码。它不是后绑定的、调度查找的-如果用户没有点击页面,你不会看到运行时错误。ASP+开发者可以使用Visual Basi.NET完整的威力而不是VBScript。并且第一次,他们可以使用Perl、Python和其它流行语言,如果他们这么选择的话。 Petrusha: 服务端的JavaScript现在也能被编译? Hejlsberg: 没错。 Goodhew: .NET框架使得使用脚本语言就象用具有完全特性的语言一样,因为它们现在访问的是一个真正的编程框架并且访问的是同一基类API。你应该看看搞Jscript实现的伙计们都已经实现了什么。[编注:Jscript是微软对ECMA 262语言规范(ECMAScript 版本 3)的实现,只有一些很小的例外(为了保持向后的兼容性),Jscript是对ECMA标准的完整实现]。所以.NET平台提供了一个公共语言框架,对脚本写作者来说,具有极大的好处。 Osborn: 我们已经讨论关于Java、C++和脚本。在PDC[译注:(微软)职业开发者会议],我听很多人争论.NET IL(IL是微软中间语言,所有编译器都必须产生它以运行在.NET框架上)和运行于Java虚拟机中的Java字节码并没有什么不同。从你的谈话中,显然你并不同意这一点。你介意进一步评论它们之间的区别吗? Hejlsberg: 好的。首先,IL的思想是一个很老的思想了。你可以追溯这个概念到UCSD Pascal p-machine(一个早期的个人计算机Pascal实现)或者Smalltalk。P-code曾被Basic和Visual Basic使用,Word的一个组成部件,内部使用p-code引擎,因为它更精简。所以,p-code并不是什么新东西。 我认为,我认为我们使用的IL的方式对此感兴趣:我们给你一个选择-如果你愿意-你可以控制把IL编译或翻译为本地代码的时机。实际上,使用受管制的 C++,你可以直接从源程序生成本地代码。受管制的 C++还可以生成IL,就象C#和VB那样。当你安装你的代码时,我们给你一个编译选项,可把IL编译成本地代码。因此,当你运行它们时,就不会有即时编译负担。我们还给你提供了一个动态运行和编译代码的选项-即时编译。有了IL,就给你带来了很多便利,比如它提供了这些能力:移植到不同的CPU结构并引入真正的类型安全并在此之上创建安全的系统。 我认为我们IL的设计和Java字节码关键的不同在于,我们做出了超前的决定-不用解释器。我们的代码永远本地运行。因此,即使产生IL,你也不会运行解释器。我们还有不同风格的JIT。对于精简框架,我们有EconnoJIT,就象我们称呼它的一样,它是一个非常简单的JIT[编注:精简.NET是.NET框架的一个子集,是为移植到其它设备和平台设计的]。对于桌面版,我们有完全功能的JIT。我们甚至有可和我们的C++编译器共用一个后端的JIT。不过,这都会比较耗时,因此你只应该在安装时使用它们。 一旦你做出偏向于执行本地代码而不是解释码的决定,它就会深深地影响IL设计。它改变了应该包括那些指令,应该包括哪些类型信息,以及它应该如何传输。如果你仔细看看两个IL[译注:即.NET IL和Java字节码],你就会发现它们非常不同。从某种意义上讲,我们的IL是类型中立的。指令里没有指定参数类型的信息。进一步说,它是靠已经压栈的东西推断出来的。这种方式使IL更为精简。无论如何,一个JIT编译器需要知道哪些信息,因此没有理由在指令里携带它们。所以,最终我们做出了不同的设计决定,而这使得容易把IL翻译成本地代码。 Osborn: 解释方式和你描述的方式有何不同? Hejlsberg: 解释器的核心是一个循环-从p-code流取得一些字节,然后进入一个大大的switch[译注:类似于程序语言里的switch...case]声明:"哦,这是ADD指令,因此它到这儿来,但是这不是…"等等。 解释器模拟CPU。我们反其道而行之,我们只走一条道,我们一直都走一条道,我们把指令翻译为机器码。现在,在EconoJIT的情况下,机器码实际上非常简单,它只创建一个调用和压栈指令的列表,并且调用运行时帮助器,然后运行时帮助器替换这个列表。当然,这个代码比解释器代码执行得快。 Osborn: 让我用一句话来总结一下:你们完全编译代码。因此当你编译完时,字节已经完全准备好运行了,尽管从IL翻译成机器码的时机可能不同。 Hejlsberg: 是的。但是,如果它是在一个内存受限的小设备的环境里,有可能当运行完就被扔掉了。 Osborn: 让我们进入语法细节。我在想,C#是否包括对正则表达式的内建支持。我没有在语言参考里看到它,或许它可能在别的什么地方吧。 Hejlsberg: 首先,在基类库里有一个正则表达式类。我们并没有在语言里加入对正则表达式的任何直接支持,但是,实际上我们有些非常类似的特性。并不值得对它们做重大的处理。但是,比如当你需要指定一个时候-我们给你这个能力去写一个逐字字符串而不需要你每次写两个后斜杠。当你写正则表达式时并且当你的正则表达式里的引号还套引号时,它实际上有极大的帮助。虽然这个帮助不足挂齿,但显然其核心在.NET框架里,而这个框架可以被任何编程语言共享。 Osborn: C#和Java名字空间看起来不同。它们是否概念相同而实现上不同? Hejlsberg: 概念上是的,但是在实现上非常不同。在Java里,包名也是物理的东西,它指定了你的源代码文件的目录结构。在C#中,物理包和逻辑名称完全独立,无论你如何称呼你的名字空间,它都和你的实际代码的物理包不相关。这就给你更多的弹性-把物理上分布的单元包装在一起,并且不强迫你建很多的目录。在语言自身,有很多很明显的区别。在Java里,包也是你的物理结构,因此,Java源文件必须在正确的路径里,并且只能包含一个公开类型或者一个公开的类。因为C#没有那种物理和逻辑上的绑定,所以你可以任意命名你的源文件。每一个源文件都可以被多个名字空间使用并且可以带有多个公开类。进一步讲,你可以把所有的源码写在一个大文件里,或你可以把它们分散到交叉的小文件中去。概念上讲,C#编译时发生了什么-你给编译器提供了所有构成你的工程的源文件,然后它只管前进并指出该干什么。 Osborn: 我有一个关于泛型编程的问题:你认为它是个重要的概念吗?它应该成为面向对象语言的一部分吗?如果是的话,你们把泛型编程加为C#的一部分的计划如何? Goodhew: 好的。在第一个版本里包括泛型编程的愿望受到了限制。并不象每一个人以为的那样,微软并没有无限制的资源。在这第一个版本里,我们不得不做一些困难的决定。 Osborn: 有多少人参与开发C#? Hejlsberg: 语言设计组由4个人构成,编译器组由另外五个开发人员构成。 Petrusha: 框架呢? Hejlsberg: 那就多了,整个公司都被卷入了。 Goodhew: 就整个Visual Studio和.NET平台组而言,我们的部门大概有千人左右。包括程序管理人员、开发人员、测试人员,包括所有创建例程、框架、运行时、ASP编程模型的人员以及其它所有的人比如我,管理层的。 Hejlsberg: 就你刚才所说的泛型方面,我明确地认为它是个非常有用的概念,并且你当然可以列举出发生在学术界和业界所有的泛型研究。模板是该问题的一个解决方法。在我们内部讨论中,我们决定要在新平台里做这个事情。但我们真正喜欢做的是让底层的运行时理解泛型。这和如何创建泛型原型是不同的。用Java的"擦除"概念系统里没有真正的泛型知识。如果公共语言运行时理解泛型的概念,多种语言就可以共享这个功能。你可以在一个地方用C#写一个泛型类,别的人用别的语言也可以使用。 使泛型成为运行时的一部分还可以使你更有效率的做某些事情。泛型初始化的最理想的时间是在运行时。如果用C++,模板的初始化发生在编译时,你有两个选择:听任你的代码膨胀或试图在链接时去除掉一些膨胀代码。但是,如果你有多个应用,你可能会忘记这一点,你将只能得到膨胀的代码。 如果把泛型的知识纳入公共语言运行时,则运行时可以理解-当一个应用或组件请求一个"Foo"列表时,它首先会问:"我已经有了一个初始化的"Foo"列表了吗?"如果是,就用那一个。实际上,如果Foo是一个引用类型,并且我们设计正确的话,我们可以让所有引用类型共享初始化。对于值类型,比如整型和浮点型,我们可以为每一个值类型创建一个初始化,但这应该在应用请求时才做。为了把泛型加入运行时,我们已经做了大量的设计工作和必要的基础性工作。 你先前提到的关于IL的东西是有意思的,因为加入泛型的决定影响了IL的设计。如果IL指令嵌入类型信息,如果,例如,一个"加"指令不再是个"加"了,而是一个整数"加"或是浮点数"加"或是一个双精度数"加",你就把类型信息硬加入到了指令流里,并且在这一点上来说IL不是泛型的。我们的IL格式实际上是真正的类型中立的。并且,为了保持类型中立,我们可以迟些时候加入泛型而不会给我们带来麻烦,至少不会太麻烦。这也是我们的IL和Java的字节码看起来不一样的原因之一。我们IL类型中立。"加"指令可以加栈顶的任何两个东西。在泛型世界,当它被初始化时,它可以被翻译成不同的代码。 Osborn: 所有.NET语言都可获得泛型能力吗? Hejlsberg: 是的。微软剑桥研究院已经创建了一个支持泛型能力的公共语言运行时和C#编译器的版本,我们正在研究如何尽快使其前进。第一个版本是不可能加入泛型了,我们知道的就这么多。但是我们正在工作以确保我们在第一个版本里做了正确的事情从而使泛型可以适用于整个蓝图。 Osborn: C#和.NET框架以及Visual Studio的下一个版本计划发行日期是? Goodhew: 唔,我们为来这儿参加PDC的6500名人员带来了技术预览版。我们希望2000年秋季的某个时间发布beta版,然后在准备好以后,我们发布发行版。我们所做的一个真正令人激动的事情是看看Windows2000发行版发布进行的如何,以让关键客户参与到合作开发和合作部署的进程中来。关于.NET框架和Visual Studio.NET,我们将再次和客户一起工作以决定最终产品的发行日期。我们打算让他们告诉我们什么时候产品该就绪了。并且,因为有真正的客户参与到这个进程中来,我们将获得更好的产品质量。这种做法的不利的一面是使产品开发和发布的进程有点不确定。但这是根本性的改变。我们在寻找一个打破质量障碍的产品发行方式,而不仅仅是挑一个武断的日期说我们要发货了。 Osborn: 因此,不是一个代码完成的日期,我们在寻找一个"准备好出发"的日期? Goodhew: 是的,没错。我认为开发者将会发现Visual Studio.Net发行版是微软历史里最高质量的发行版本之一。 Osborn: 你们已经把C#提交给ECMA[译注:欧洲计算机制造商协会]。标准化真的是一个严肃的目标吗?你希望在其它平台上也可使用C#吗? Hejlsberg: 的确如此!把C#作为一个可能的标准提供给业界当然是我们的目标,这也是我们把它提交给ECMA的原因之一。在引导这个有着公共语言基础设施的公共设计的语言的进程中,我们当然希望得到ECMA的支持。关于公共基础设施,我的意思是指这个规范所规定的一个核心类库集,如果其它公司使用其它平台实现它,他们有理由期望发现可以在他们的程序里利用这些类。 Goodhew: 我想指出的是我们正在和ECMA做真正的开放标准。当ECMA为C#和公共语言基础设施达成标准后,在ECMA的版权和授权政策下,真正的开放将可实现。任何客户、任何人都可以被授权ECMA C#标准,子集之,超集之,并且不必付版税。他们可以在任何平台和任何设备实现之。我们完全希望人们那么做。这和我们的竞争者根本不同。他们徘徊在标准之外,寻找某某人去为他们私有的语言贴上印花。 John: 我在早餐和午餐时听说:"如果微软没有把COM搞到基础设施中去,平台会多么具有可移植性?" Hejlsberg: 完全可能。COM并非C#和公共语言基础设施标准化之必须。根本不是。C#有一个完备丰富的类模型,而COM则是从另外一个视角看待应用的互操作性。但是,C#和公共运行时的核心中从未说过必须要有COM、 GUID、 HRESULT、 AddRef 或 Release等等。一个都没有。.NET 公共语言运行时彻底摒弃了COM,但它还是给了你巨大的COM互操作能力。鉴于先前所述,我仍然认为它将非常重要,但绝非不可或缺。 Goodhew: 我认为这些评论起因于我们公开的最初版本的语言规范。微软在某次会议上把它写进了规范。在那次会议上,我们认为按照微软平台来说这是非常重要的。结果,我们在规范里多次引用COM和DLL这样东西。DLL是如何在已给定平台上激活本地代码的更多的一般性问题中的一个特例。对于纳入标准化组织以及和象IBM的人(我们和他们一起制订SOAP规范)一起工作的一个好处是我们可以不做任何这样的提及,以防止在规范的未来版本里,把我们自己绑死或锁定在象COM框架这样的东西上。 就象Anders说的那样,COM互操作能力和COM支持对我们和已有的微软客户来说是极其重要的。我认为为了在.NET支持COM我们做了大量的工作。但是,业界的人们已经阅读了大量的我们对COM和DLL字眼引用的东西,他们由此推论.NET仅仅是为Windows平台设计的,这是完全错误的。 Hejlsberg: 并且,我认为就象COM的互操作能力对于微软和在微软平台上构建解决方案的客户很重要一样,C#和公共语言基础设施的标准化将允许在任何其它平台上选择实现这个语言以加入意义重大的互操作能力。 Osborn: 所以你们将不会坚持应该有个什么"纯C#"和"纯.NET"的实现? Hejlsberg: 什么叫"纯"?真正有多少"纯"Java应用存在?我冒险猜测一下,非常非常少。那就是我估计的数量。让我们承认这一点,人们希望能利用他们已存在的代码。不可能叫那些公司把什么东西都扔掉。 Goodhew: 你和Roger Sessions交流过吗?[编注:Roger Sessions是ObjectWatch公司的CEO,并且是《COM+ and the Battle for the Middle Tier》的作者] 。 Osborn: 没有。 Goodhew: Roger谈到了EJB规范的相关章节,那儿讲了卖方[vendor]许可扩展。毫不奇怪,卖方扩展包括诸如事务管理、安全、消息以及其它更多的方面,这在构建企业级系统中是相当重要的。在一篇文章[译注: http://www.objectwatch.com/issue_24.htm]里,Sessions粗略地列举了11个领域的机能,这是可容许的卖方规范实现。因此,如果你选择IBM Websphere作为你的EJB实现,你为你的EJB应用写的代码将不可避免地被锁定在Websphere。Java是100%纯和100%可移植的概念是不正确的。在IBM的开发者工作站点上,有一个伟大的专访[译注:http://www-106.ibm.com/developerworks/features/gosling/index.html]。James Gosling直接指出了这一点。他说,是的,整个"写一次到处运行"、"100%纯的东西"真是个愚蠢的想法,更多的是属于营销上东西。他说,实际上,"我们并不认为我们能够交付这一切,基本上,我们办不到"。这就是这个语言的发明者说的,不存在什么纯粹性和可移植性。 Osborn: 我们有没有遗漏一些没透露的C#的伟大的特性或创新,你愿意补充一下吗? Hejlsberg: 关于.NET框架,隐含地,也包括C#,我想提的一点是:它是构建分布式应用的手段。并非很久以前,我们创建两阶层的客户/服务应用,然后对象协议如CORBA、 IIOP、 RMI、和DCOM 接踵而至。这种类型的编程是EJB-(CORBA或RMI的底层实现[译注:DCOM除外])的基础。我们已经会构建这种强连接式的分布式系统,但它们不具备伸缩性。它们在WEB上不能够伸缩因为它们是有状态的,它们在服务端保持状态,你不能够转入另一台机器,把它插入并让相关东西复制自己。 当初,当我们坐下来着手设计.NET框架时,我们回头看了看Web上究竟发生了什么。它正在变成松散连接、非常分布式的世界。我们努力理解它对潜在的编程模型的影响。因此,我们从根本上假定分布式的应用是构建在松散连接、无状态风格的。依此,我们做出的设计可提供巨大的伸缩性。你只管扩展。你转入更多的框架并且把它们插入。一旦做出了这个根本性的假设,一切就随之改变。它改变了怎样设计你的根本服务,怎样设计你的消息,甚至是怎样设计你的用户界面。这是一个新的编程模型。我们已经选择了XML和SOAP作为使这个模型工作的方式。它们被深深地集成到.Net。并且这种集成对于我们在设计.NET框架时做出的每一个决策是如此核心,以至于它不是那种你只是进来蜻蜓点水地逛一逛就可以的东西。 Osborn: 你能指出一些对程序员来说明显特别的地方吗? Hejlsberg: 一个相当好的例子是XML是如何被集成到C#中的。C#中有特性[译注:即attribute,关于名词译法的说明,上文有描述]的概念,它允许你向类型和成员加入宣称性信息。就象你可以说某个成员是公有的或私有的一样,你可能还想说这个是事务的,或者这个假定是个Web service,或这个假定被以XML方式的序列化支持。因此,我们加入特性以提供一般性机制,但是我们在所有的Web service和XML基础设施中都用到了它。我们还给你用特性修饰类和字段的能力。在你的类中,你可以说"当这个类型变成XML时,它应该变成"this"标签名,并且属于"this"XML名字空间。"你将有能力指定一个字段变成一个元素,而另外一个变成属性[译注:此处指XML中的属性]。你还能够控制XML的模式[译注:即schema];在你的类声明的地方控制它,这样,所有附加的宣称性信息就都可以获得了。一旦以该方式正确地使用特性修饰你的C#代码,系统就可以简单把它转化成XML中一个指定的类,在线上传输,当它传回时,就可以在另一端重建该对象。这都是在一处定义完成的。它不象传统的定义文件或多种信息和命名模式。它就在那儿。当你在IDE中创建它们时,它就给了你完整的声明。我们还可以提供高级工具,让它帮你做这个事。 我知道我有点离题了,但是我们提供的这些基础设施的确令人兴奋。单单因为我们有这些特性,你就可以请求XML序列化基础设施或Web service基础设施把已给出的类翻译成XML。当你这么做了,我们实际上将为这个类配上XSD模式,并且我们将创建一个特别的解析器,它是从我们一般的XML解析器派生出来的(.NET基类的一部分),并且重载方法并加入逻辑,因此它是专门为那个模式服务的。所以,我们已经初始化好一个解析器,可以本地代码的速度解析XML。如果它不正确,我们将给你一个体面的出错信息,它可以精确地告诉你是什么出了问题。我们可以在代码缓存基础设施中缓存它,它将坐等直到下一次一个具有同样模式的类来临并将发生作用,"嘭!",我的意思是,难以置信,难以置信的生产能力!
W wr960204 Unregistered / Unconfirmed GUEST, unregistred user! 2003-09-23 #39 比尔盖茨的一段代码: if (公司=Borland) then begin %1几率数据字节向左移一位 end;
涤 涤新 Unregistered / Unconfirmed GUEST, unregistred user! 2003-10-07 #40 Java编译器的源代码不是早就公布了吗? 但国内连一本介绍面向对象语言编译原理的书都没有, 大学里那些讲授编译原理的教授们应该反省了, 我们什么时候才能搞出自己的Delphi,C#...