C#首席設計師Anders Hejlsberg專訪

    文章摘要:Anders Hejlsberg 是微軟.Net 框架設計師、C# 程序語言首席設計師。他所開發的Turbo PascalDelphi 獲得了極大的成功。他最新的C#[ 發音爲"See sharp"] 又爲何物呢?假定.NET 平臺上支持多語言,那爲什麼選擇C# 而不是Visual BasicC++ 甚至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 GoodhewO'ReillyWindows 編輯Ron Petrusha

Osborn:

  我已經看到一些關於C#[ 發音爲"See sharp"] 的新聞故事,我注意到有很多似乎傾向於這樣的觀點- 或理論上說-C# 不是Java 的克隆就是Java 的微軟替代物。如果你來寫這個標題,你希望人們怎麼評論這門語言?

Hejlsberg :

  首先,C# 不是Java 的克隆。在設計C# 期間,我們考察了很多種語言,如C++JavaModula  2CSmalltalk 等。很多語言都有我們感興趣的相同的核心思想,比如深度面向對象、簡化對象等等。

  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:

  是的。這是我的首要目標之一。我們談論一切如何都是對象,這也非常關鍵。以前象SmalltalkLisp 語言都可以這麼做,但代價昂貴。我認爲C# 包含一些優美有趣的創新使得組件開發容易些。例如裝箱和拆箱的概念。裝箱可以使一個值類型的值轉換爲一個對象,拆箱可以使一個對象轉換爲一個簡單類型的值。這在以前或許也有,但我們把它應用於語言的方式是一種優美的創新。

  我們努力避免用" 象牙塔" 的方式設計C#.Net 框架。我們承受不起重寫我們所有的軟件的負擔。業界也負擔不起,特別是今天我們正轉移到Internet 時代。你要善於利用你已經擁有的。所以,我認爲互操作性也是關鍵的。我們致力於爲程序員提供所有符合Internet 標準的可互操作的正確的解決方案,例如HTTPHTMLXML 以及微軟已經存在的技術。所以你不會有如墜深淵的那一刻- 發現新的.NET 框架下沒有提供你用的一些東西,或者你意識到你想利用一些已經存在的API 或組件的時候。你已經看到我們已把所有COM 的互操作能力內建入語言和公共運行時;你已經看到可以使用DllImport 特性導入已存在的DLL[ 動態連接庫] ;你已經看到即使那些都不能遂你願,我們也有不安全代碼的概念。不安全代碼允許你寫使用指針的內聯C 代碼,可以做不安全的造型轉換,可以抑制內存從而使其不會被意外地垃圾收集[ 譯註:此處用作動詞J]

  關於不安去代碼有很多爭論,人們似乎認爲我們在吸毒或是在幹什麼別的壞事。我認爲這是個誤會。代碼不會僅僅因爲標記了" 不安全" 就表示它不受管制。當然,我們不會扔出不安全的指針使人們容易受到從Internet 下載的不安全代碼的攻擊。不安全代碼被深深地約束在安全的環境裏。我們提供這樣的彈性:1. 呆在受管制的代碼箱裏完成工作而不會墜入深淵;2. 轉入一個不同的語言使用一個不同的編程模型寫本地代碼。如果你停留在這個箱子裏,我們會使代碼更加安全,因爲系統知道它要幹什麼。事實上,即使你寫不安全代碼也不意味着你離開了受管制的空間。你的不安全代碼會變得更有效率。

Osborn:

  請給我多講一些在受管制的環境裏處理不安全代碼的機制。

Hejlsberg:

  好的。描述受管制的執行環境比如SmalltalkJava.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 BasicC++ 甚至COBOL ?是什麼使C# 如此引人注目?

Hejlsberg:

  首先,C# 可以使我們從一張白紙開始。也就是說,我們沒有任何向後兼容性的負擔。這顯然會使事情簡化,無論從是從實現的立場還是從使用的立場都是這樣。例如,在C# 中,我們只有一類類型,並且總是被垃圾收集。而另一方面,受管制的C++ 有兩套。因爲它要保留非垃圾收集風格的編程。因此,在C# 中,只需要你理解一些簡單的概念。

  語言是一個有趣的東西,它是一種口味;語言又是一件嚴肅的事情,它是程序員選擇的一種生活方式。我是指,我們意識到我們不能走出來說," 這兒有個平臺,你只可以使用一個基礎語言。" 即使在那個平臺上用一種語言可以做所有的事情,人們還是可能不喜歡它的語法。他們可能喜歡大括號或者一些其它的程序塊分界符。那是他們熟悉的。那是使他們感覺舒服並且富有生產力和能力的。我們對待C# 的方式僅僅是爲認爲語言太複雜的C++ 程序員和認爲丟失了一些CC++ 語言特性的Java 程序員提供一個可選物。我們尋求一個簡化C++ 的方式並投入到一個多語言的平臺中,它提供更大的互操作性,並且它提供完備的組件概念等等。

Goodhew:

  一件有趣的事情來自於我們對開發者跟蹤調查,60% 以上的職業開發人員使用兩種或更多的語言去創建他們的應用。特別是當我們問他們都用哪些開發工具的時候,我們得到的答案是:沒有哪一種開發語言將會是終結者並且所有程序員都會使用它。正如Anders 早先所說,人們期望某種能夠滿足他們所做或他們所感的語法。這是一個個人選擇。這也是整個.NET 平臺所關心的- 提供給開發者一個語言實現選擇。我想我們做了件漂亮的工作。你基本上可以在Visual Basic.NETC# 中做同樣的事情。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:

  我不知道這對那些使用象VBScriptJscript 腳本語言的有什麼作用?

Hejlsberg:

  .NET 框架下奇妙的事情之一是使腳本語言能夠編譯。看看ASP+ ,現在,實際上,在你的頁面裏運行的是真正編譯的代碼。它不是後綁定的、調度查找的- 如果用戶沒有點擊頁面,你不會看到運行時錯誤。ASP+ 開發者可以使用Visual Basi.NET 完整的威力而不是VBScript 。並且第一次,他們可以使用PerlPython 和其它流行語言,如果他們這麼選擇的話。

Petrusha:

服務端的JavaScript 現在也能被編譯?

Hejlsberg:

沒錯。

Goodhew:

  .NET 框架使得使用腳本語言就象用具有完全特性的語言一樣,因爲它們現在訪問的是一個真正的編程框架並且訪問的是同一基類API 。你應該看看搞Jscript 實現的夥計們都已經實現了什麼。[ 編注:Jscript 是微軟對ECMA 262 語言規範(ECMAScript 版本 3) 的實現,只有一些很小的例外(爲了保持向後的兼容性),Jscript 是對ECMA 標準的完整實現] 。所以.NET 平臺提供了一個公共語言框架,對腳本寫作者來說,具有極大的好處。

Osborn:

  我們已經討論關於JavaC++ 和腳本。在PDC[ 譯註:(微軟)職業開發者會議] ,我聽很多人爭論.NET ILIL 是微軟中間語言,所有編譯器都必須產生它以運行在.NET 框架上)和運行於Java 虛擬機中的Java 字節碼並沒有什麼不同。從你的談話中,顯然你並不同意這一點。你介意進一步評論它們之間的區別嗎?

Hejlsberg:

  好的。首先,IL 的思想是一個很老的思想了。你可以追溯這個概念到UCSD Pascal p-machine (一個早期的個人計算機Pascal 實現)或者SmalltalkP-code 曾被BasicVisual 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 ILJava 字節碼] ,你就會發現它們非常不同。從某種意義上講,我們的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 格式實際上是真正的類型中立的。並且,爲了保持類型中立,我們可以遲些時候加入泛型而不會給我們帶來麻煩,至少不會太麻煩。這也是我們的ILJava 的字節碼看起來不一樣的原因之一。我們IL 類型中立。"" 指令可以加棧頂的任何兩個東西。在泛型世界,當它被初始化時,它可以被翻譯成不同的代碼。

Osborn:

  所有.NET 語言都可獲得泛型能力嗎?

Hejlsberg:

  是的。微軟劍橋研究院已經創建了一個支持泛型能力的公共語言運行時和C# 編譯器的版本,我們正在研究如何儘快使其前進。第一個版本是不可能加入泛型了,我們知道的就這麼多。但是我們正在工作以確保我們在第一個版本里做了正確的事情從而使泛型可以適用於整個藍圖。

Osborn:

  C#.NET 框架以及Visual Studio 的下一個版本計劃發行日期是?

Goodhew:

  唔,我們爲來這兒參加PDC6500 名人員帶來了技術預覽版。我們希望2000 年秋季的某個時間發佈beta 版,然後在準備好以後,我們發佈發行版。我們所做的一個真正令人激動的事情是看看Windows2000 發行版發佈進行的如何,以讓關鍵客戶參與到合作開發和合作部署的進程中來。關於.NET 框架和Visual Studio.NET ,我們將再次和客戶一起工作以決定最終產品的發行日期。我們打算讓他們告訴我們什麼時候產品該就緒了。並且,因爲有真正的客戶參與到這個進程中來,我們將獲得更好的產品質量。這種做法的不利的一面是使產品開發和發佈的進程有點不確定。但這是根本性的改變。我們在尋找一個打破質量障礙的產品發行方式,而不僅僅是挑一個武斷的日期說我們要發貨了。

Osborn:

因此,不是一個代碼完成的日期,我們在尋找一個" 準備好出發" 的日期?

Goodhew:

是的,沒錯。我認爲開發者將會發現Visual Studio.Net 發行版是微軟歷史裏最高質量的發行版本之一。

Osborn:

你們已經把C# 提交給ECMA[ 譯註:歐洲計算機製造商協會] 。標準化真的是一個嚴肅的目標嗎?你希望在其它平臺上也可使用C# 嗎?

Hejlsberg:

  的確如此!把C# 作爲一個可能的標準提供給業界當然是我們的目標,這也是我們把它提交給ECMA 的原因之一。在引導這個有着公共語言基礎設施的公共設計的語言的進程中,我們當然希望得到ECMA 的支持。關於公共基礎設施,我的意思是指這個規範所規定的一個核心類庫集,如果其它公司使用其它平臺實現它,他們有理由期望發現可以在他們的程序裏利用這些類。

Goodhew:

  我想指出的是我們正在和ECMA 做真正的開放標準。當ECMAC# 和公共語言基礎設施達成標準後,在ECMA 的版權和授權政策下,真正的開放將可實現。任何客戶、任何人都可以被授權ECMA C# 標準,子集之,超集之,並且不必付版稅。他們可以在任何平臺和任何設備實現之。我們完全希望人們那麼做。這和我們的競爭者根本不同。他們徘徊在標準之外,尋找某某人去爲他們私有的語言貼上印花。

John:

  我在早餐和午餐時聽說:" 如果微軟沒有把COM 搞到基礎設施中去,平臺會多麼具有可移植性?"

Hejlsberg:

  完全可能。COM 並非C# 和公共語言基礎設施標準化之必須。根本不是。C# 有一個完備豐富的類模型,而COM 則是從另外一個視角看待應用的互操作性。但是,C# 和公共運行時的核心中從未說過必須要有COM GUID HRESULT AddRef Release 等等。一個都沒有。.NET 公共語言運行時徹底摒棄了COM ,但它還是給了你巨大的COM 互操作能力。鑑於先前所述,我仍然認爲它將非常重要,但絕非不可或缺。

Goodhew:

  我認爲這些評論起因於我們公開的最初版本的語言規範。微軟在某次會議上把它寫進了規範。在那次會議上,我們認爲按照微軟平臺來說這是非常重要的。結果,我們在規範裏多次引用COMDLL 這樣東西。DLL 是如何在已給定平臺上激活本地代碼的更多的一般性問題中的一個特例。對於納入標準化組織以及和象IBM 的人(我們和他們一起制訂SOAP 規範)一起工作的一個好處是我們可以不做任何這樣的提及,以防止在規範的未來版本里,把我們自己綁死或鎖定在象COM 框架這樣的東西上。

  就象Anders 說的那樣,COM 互操作能力和COM 支持對我們和已有的微軟客戶來說是極其重要的。我認爲爲了在.NET 支持COM 我們做了大量的工作。但是,業界的人們已經閱讀了大量的我們對COMDLL 字眼引用的東西,他們由此推論.NET 僅僅是爲Windows 平臺設計的,這是完全錯誤的。

Hejlsberg:

  並且,我認爲就象COM 的互操作能力對於微軟和在微軟平臺上構建解決方案的客戶很重要一樣,C# 和公共語言基礎設施的標準化將允許在任何其它平臺上選擇實現這個語言以加入意義重大的互操作能力。

Osborn:

  所以你們將不會堅持應該有個什麼"C#"".NET" 的實現?

Hejlsberg:

  什麼叫"" ?真正有多少""Java 應用存在?我冒險猜測一下,非常非常少。那就是我估計的數量。讓我們承認這一點,人們希望能利用他們已存在的代碼。不可能叫那些公司把什麼東西都扔掉。

Goodhew:

  你和Roger Sessions 交流過嗎?[ 編注:Roger SessionsObjectWatch 公司的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 應用寫的代碼將不可避免地被鎖定在WebsphereJava100% 純和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-CORBARMI 的底層實現[ 譯註:DCOM 除外] )的基礎。我們已經會構建這種強連接式的分佈式系統,但它們不具備伸縮性。它們在WEB 上不能夠伸縮因爲它們是有狀態的,它們在服務端保持狀態,你不能夠轉入另一臺機器,把它插入並讓相關東西複製自己。

  當初,當我們坐下來着手設計.NET 框架時,我們回頭看了看Web 上究竟發生了什麼。它正在變成鬆散連接、非常分佈式的世界。我們努力理解它對潛在的編程模型的影響。因此,我們從根本上假定分佈式的應用是構建在鬆散連接、無狀態風格的。依此,我們做出的設計可提供巨大的伸縮性。你只管擴展。你轉入更多的框架並且把它們插入。一旦做出了這個根本性的假設,一切就隨之改變。它改變了怎樣設計你的根本服務,怎樣設計你的消息,甚至是怎樣設計你的用戶界面。這是一個新的編程模型。我們已經選擇了XMLSOAP 作爲使這個模型工作的方式。它們被深深地集成到.Net 。並且這種集成對於我們在設計.NET 框架時做出的每一個決策是如此核心,以至於它不是那種你只是進來蜻蜓點水地逛一逛就可以的東西。

Osborn:

  你能指出一些對程序員來說明顯特別的地方嗎?

Hejlsberg:

  一個相當好的例子是XML 是如何被集成到C# 中的。C# 中有特性[ 譯註:即attribute ,關於名詞譯法的說明,上文有描述] 的概念,它允許你向類型和成員加入宣稱性信息。就象你可以說某個成員是公有的或私有的一樣,你可能還想說這個是事務的,或者這個假定是個Web service ,或這個假定被以XML 方式的序列化支持。因此,我們加入特性以提供一般性機制,但是我們在所有的Web serviceXML 基礎設施中都用到了它。我們還給你用特性修飾類和字段的能力。在你的類中,你可以說" 當這個類型變成XML 時,它應該變成"this" 標籤名,並且屬於"this"XML 名字空間。" 你將有能力指定一個字段變成一個元素,而另外一個變成屬性[ 譯註:此處指XML 中的屬性] 。你還能夠控制XML 的模式[ 譯註:即schema] ;在你的類聲明的地方控制它,這樣,所有附加的宣稱性信息就都可以獲得了。一旦以該方式正確地使用特性修飾你的C# 代碼,系統就可以簡單把它轉化成XML 中一個指定的類,在線上傳輸,當它傳回時,就可以在另一端重建該對象。這都是在一處定義完成的。它不象傳統的定義文件或多種信息和命名模式。它就在那兒。當你在IDE 中創建它們時,它就給了你完整的聲明。我們還可以提供高級工具,讓它幫你做這個事。

我知道我有點離題了,但是我們提供的這些基礎設施的確令人興奮。單單因爲我們有這些特性,你就可以請求XML 序列化基礎設施或Web service 基礎設施把已給出的類翻譯成XML 。當你這麼做了,我們實際上將爲這個類配上XSD 模式,並且我們將創建一個特別的解析器,它是從我們一般的XML 解析器派生出來的(.NET 基類的一部分),並且重載方法並加入邏輯,因此它是專門爲那個模式服務的。所以,我們已經初始化好一個解析器,可以本地代碼的速度解析XML 。如果它不正確,我們將給你一個體面的出錯信息,它可以精確地告訴你是什麼出了問題。我們可以在代碼緩存基礎設施中緩存它,它將坐等直到下一次一個具有同樣模式的類來臨並將發生作用," 嘭!" ,我的意思是,難以置信,難以置信的生產能力!

 

 



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章