C#首席設計師Anders Hejlsberg專訪(1)轉

來源:互聯網
上載者:User
設計 作者: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 Basic.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:

     是的。但是,如果它是在一個記憶體受限的小裝置的環境裡,有可能當運行完就被扔掉了。


相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。