天天看點

msdn 訪談錄之C#程式設計二

程式員天地

Robert Hess和Jeffrey Richter(著名的程式設計作家、專欄作家和咨詢專家)的談話。

ROBERT HESS: 歡迎回來。我們正要涉及到有關C#程式設計方面的問題。為了有助于我們了解這些問題,我邀請我的好朋友Jeffery Richter到這裡來。Jeffery恰好是一名撰寫了很多程式設計書籍的程式員,他最新的一本書為Programming Server Side Applications for Windows 2000。現在您也是一位咨詢專家并且擁有自己的公司Wintellect,是嗎?

JEFFREY RICHTER: Wintellect。

ROBERT HESS: 我猜您有一個網站吧?

JEFFREY RICHTER:有,Wintellect.com。我們專門從事教育訓練、調試和廣告。

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

JEFFREY RICHTER: 是的,至今已一年有餘了,我花了很大的精力一直專攻C#的程式設計。

ROBERT HESS:已經有一年了?我想我們才剛釋出了C#。

JEFFREY RICHTER:是的,可我一直在圈内,在Microsoft的圈内,如果您願意的話。我自己在第42樓安置了一個小小的辦公室,并在那裡從事C#的研究和有關.NET這方面的工作,到現在已經一年多了。

ROBERT HESS: 這樣微軟就會對您有所幫助,因為您并不是微軟的職員……

JEFFREY RICHTER: 對。

ROBERT HESS:他們隻是幫助您的把C#當成一種語言了解,那麼您就可以寫出更多象這樣的書?

JEFFREY RICHTER:是的,他們希望我寫更多的書,我得到了幫助,發現了bug,出席了類似的一些規範會議,并與人們交流,是以我覺得學到了很多的東西,而不隻是寫書,而事實在某種程度上也對C#做出了貢獻。是以我可以告訴您,當最初開始時,我感興趣的第一個東西就是這種新的語言,我将用它來寫所有的代碼,我知道這些代碼是為可以預見的未來寫的,讓我們暫且不提。我具有非常深厚的C、C++背景,在閱讀與C#相關文檔和程式設計參考等資料一個星期之後,我就覺得已經相當精通C#了。并且在一周之内,我能夠真正地寫出一些有用的東西。

ROBERT HESS:僅僅一周之後。

JEFFREY RICHTER:是的,僅僅一周之後。因為它和C++非常類似,您知道,那裡的大括号是相同的,傳回值是相同的,參數是相同的,許多東西都是相同的。

ROBERT HESS:當繼續使用對象、析構函數、構造函數、雙冒号(::)等這些老掉牙的東西時,您似乎就要失去他們所擁有有的某些奇特的命名習慣,對嗎?

JEFFREY RICHTER:是的是的,雙冒号(::)都被點号(.)代替,箭頭号(->)也被點号代替,這樣就大大地簡化了該語言。因而對于我來說實在是太容易啦,而且它還具有時效性,我仍不得不回過頭去檢視該語言參考資料,或許查找如何重載運算符,或者某些很平常的東西,要知道,當我程式設計時,極少做一些模糊不清的事。而現在大多數東西對我來說是再自然不過的了。事實上要解決的隻是流程問題。

ROBERT HESS:既然您從事這項工作已經一年多了,那麼您注意到了在這段時間裡這種語言自身的演變嗎?是否它們今天仍然與一年以前的十分相同?

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#作為一種語言總的來說究竟怎麼樣?

JEFFREY RICHTER:嗯,正如我所說的,C#與C++非常相似,是以我很快便熟悉了。它非常非常的幹淨,我要說它是非常幹淨的。我出身于C++背景,尤其是作為一個Windows C++程式員。ANSII擁有C++規範,微軟為了展示Windows中的功能,就想在C++中保留一些技巧,并且使這些技巧看起來有點像C++中的貴族,可它們從來就沒有真正地達到要求。而微軟仍陸續增加__try、  __finally 和 __declspec等類似的東西。

ROBERT HESS:這就是您正在談論的C#。

JEFFREY RICHTER:對,當然還有C++。是以,這種語言确實有點恐怖,過了一會兒您還是不會完全弄明白,就如const的用法,當聲明一個指針或者是一個常量指針時,星号(*)究竟應放在它的前面,還是放在後面?您将無法斷定這些修飾符到底應放在該行的那個位置。我總是需要查資料。是以在C#中,由于微軟在設計時已經預先向ECMA(歐洲計算機制造商協會)做出了要求标準化的提議,是以它實在很幹淨,例如,沒有什麼是以下滑杠開始的。當然,由于本來在.NET runtime中就沒有真正的指針,是以在您的代碼中,從頭到尾都不會能見到*号和&号等此類修飾符。這樣當考慮它時,看起來幹淨,真的覺得很爽。

ROBERT HESS:難道您不覺得缺少什麼嗎?我的意思是,當我在用C程式設計時,喜歡運用指針解決問題,對指針重新分類,利用指針算法等老掉牙的東西,您就會從中獲得極大的樂趣。難道您在用C#時就不懷念它嗎?

JEFFREY RICHTER:嗯,我不得不承認,我自己總是有些喜新厭舊,但有時也有點念它。當然總的來說,有了C#和.NET framework,您就可以始終與其它語言進行互動操作(interoperate out),因而如果真的必須那樣做的話,我便用C++而不是C#程式設計了。C#也确實提供了一種不安全的關鍵詞(unsafe keyword),這樣一來,您就可以建立一個方法并且說,這是不安全的,您有權使用指針并對記憶體進行直接操作。盡管如此,我還是從未親自體驗過。至于編碼時獲得的樂趣,.NET framework和基本OS類庫提供了大量的特性,它們使程式設計變得有趣了。是以,當我不能保留虛拟記憶體并稀疏地送出,也不能在.NET framework中利用記憶體映象檔案進行工作時,至少不能直接進行時,也可以通過互動操作完成,仍然還有其它類似serialization和web服務等東西,它們有利于創作出真正有價值的應用程式,真正強大而豐富的内涵。

ROBERT HESS:如今在您的教育訓練班裡,您正在教授和灌輸這樣的東西,您還在辦C#的教育訓練班嗎?

JEFFREY RICHTER:是的,事實上剛好這一周,我給第一個C#程式設計班上課,當時班裡有兩個Visual Basic程式員,他們根本就不是面向對象的程式員,而我也沒有真正地給他們介紹過C#語言,因為我把重點放在公共語言運作庫和基類庫方面,有關C#的内容想稍後再講。但是,這兩個VB程式員在上機實習時,對C#上手很快,幾乎沒有遇到什麼麻煩,而且竟然能用其進行開發,效率也高。我十分驚訝!

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

JEFFREY RICHTER: 确實這樣。

ROBERT HESS:這些在VB中都不會用到。

JEFFREY RICHTER:正确。

ROBERT HESS:是以格式看來相當一緻。

JEFFREY RICHTER:對,相當一緻。當然,他們用大括号{}而不是begin和end,這可能使有些人不适應。但我認為,他們最多花不到5分鐘的時間就可以克服它,而且更多産。

RROBERT HESS:那麼以一個公司的立場,假如一個公司聘請您去開設一個C#教育訓練班,是以我得去發現他們是否開始考慮把公司的一些成果移植到C#,這就是您建議他們要做的事嗎?或者您認為他們應處于哪一個階段?

JEFFREY RICHTER:嗯,當然它取決于,首先他們必須決定是否要采用.NET framework作為開發平台。我認為這非常有價值,對于我來說毫無問題,那是我真正向往的平台。如果您正在開發.NET framework的應用軟體,正在編寫新的代碼,在我看來會不費吹灰之力。 C#上手實在是很容易,它是一種生機勃勃的語言,使用正确的方法您會非常多産的。我個人也相信大量的VB程式員,VB6.0程式員,将會轉向C#而不是VB7.0。

ROBERT HESS:那為什麼?

JEFFREY RICHTER:因為我認為C#揭示了公共語言運作庫(common language runtime)之中的更多的特性,使您對代碼及其所表達的方法具有更多一點的控制權。您将更直接地與runtime對話,runtime賦予了您更多的權力。

ROBERT HESS:當然,我們本身誰都不是VB程式員,是以将明确地在C基礎之上發展。

JEFFREY RICHTER: 您是對的。

ROBERT HESS:是以這正是它物有所值之處,我們有點偏離正題了。那麼作為一種語言,您喜歡C#的哪些方面呢?是更簡單、更徹底(clean)的程式設計嗎?

JEFFREY RICHTER: 嗯,主要是去掉了無用的東西。 譬如, 嗯, C#不允許您把參數作為常量(const)聲明,并且您不能擁有一個const的實體方法,而在C++中則可以。我知道某些人會認為那樣會真的喪失語言的特性,但事實在C++中,const總是會被無情地抛棄,這樣您就能在自己的代碼中為所欲為了。由于C#實在是不允許您使用const,是以它又徹底又易于了解。現在,我想我應該說:對于我,.NET frameworks真正有趣的東西就是公共語言運作庫。它定義對象如何運轉,或如何建立類型,以及是什麼定義了這些類型的行為。這樣您就擁有了一個基類庫,當然它是一個巨大的類庫,它讓您有權使用大量的東西,是以即使您願意,也不必再三重寫每一樣東西了。您選擇語言是您個人的事情,而我選擇了C#是由于它是真正優秀的高階語言,它讓我能與framework對話。但在某種程度上,運用.NET runtime和基類庫真正最佳的語言應該是中間語言(immediate language)彙編語言。

ROBERT HESS:哈!談到彙編語言啦?

JEFFREY RICHTER:是的,談到彙編語言了。我的意思是,它使您完全有權通路平台的底層,但在彙編語言的環境中效率會很低,有這麼多的程式您必須一行一行地寫。是以,C#語言高出了一個層次。而在C#中的有些性能并不是很常用,是以象Anders 這樣的C#設計者已決定不必将其公開了。在某些情況下,為了通路C#沒有提供的runtime功能,我可能會求助于另外一種語言。但總的來說,C#是最高層的語言,它允許我在這樣的環境中按自己的需求解決大量的問題,而且效率極高。

ROBERT HESS:并不是所有的問題,而僅僅隻是大部份?

JEFFREY RICHTER:不,極少會出現這種情況:我還需要通路某些東西,而C#卻不讓通路。這是另外一方面,我隻是認為大家非常容易忘卻的是,當您想要通路.NET的一些功能而C#或某些語言卻不提供給您時,可以轉到别的語言。隻需編碼建立這個方法,可能是一個靜态方法(static method),類中的靜态方法,用APL或COBOL或凡是您選擇的語言,或許派生,然後用某些語言實作實體方法,而這種語言可能真的讓您通路某些底層功能。是以,我認為這是一個功能非常強大的範例,以前我從未真正地領會過要選擇最佳的語言去完成工作。

ROBERT HESS:好了,我打賭各位觀衆可能想要看一些C#代碼的例子,以便能了解我們談論到的一些問題。您有例子示範給我們看嗎?

JEFFREY RICHTER:有。我确實的帶來了一個源代碼檔案,裡面有一些例子,能勉勉強強地應付,在節目結束後,我會給您的。歡迎您把它上傳到網站上,以讓大家可以下載下傳。是以在這裡,如果你樣喜歡的話,我首先要示範的是:在C#中,每一個方法必須位于類中。沒有全局方法,也沒有位于類之外的變量,是以每一樣東西都會被限定在一定的範圍内。

using System;

class App {

   public static void Main () {

      Console.WriteLine("Hello World");

   }

}

這是一個必須保留的hello world程式,非常簡單。在程式裡,有一個類叫App,在這個類裡,我擁有自己的一個Main方法,并且Main是一個靜态方法,因為它必須從外面調用。我們不必擁有App的一個執行個體就可以調用Main。在我這個例子裡,Main傳回void,并且沒有接受參數。簡單地在Main的内部,它調用了Console.WriteLine,在顯示器上面顯示出"Hello World"。是以這是您可以寫的、能學到相關概念的最小程式了。

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

JEFFREY RICHTER: Main是預設的,它具有大寫字母M,小寫字母a-i-n ,因為C#是字母大小寫敏感的語言,象C++ 而不象VB 和.NET 。是以當編譯器編譯代碼時,将尋找一個叫做Main的靜态方法,然後再使用它。然而有一個編譯器的指令行,它可以覆寫掉Main并選取其中不同的一個。順便說一下,事實上這是一門很有用的技巧。一些人把多個Main放到一個單個的應用程式裡,以便進行組測試,當編譯時,可以設定不同的開關執行不同的Main,以便測試特定的元件。

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<ia.length, i++)"也做同樣的工作,但如果您想要周遊所有的元素的話,這種方式有些笨拙以至難于遵循,是以一直持續不斷地做十分相同的事情,我想會更加容易。

JEFFREY RICHTER:對,精辟。盡管如此,我會給您一點提示,由于foreach有點酷,也十分精巧,是以省去了大量的編碼。它也另外做一些有關類型轉換(casting)的工作,這對您同樣也有好處。是以一般來說,當我寫一個循環時,我通常會以foreach開始,然後當我繼續編碼時,有時經常地,我随後認識到我需要一個疊代器(iterator),需要一個從0到實際數字的X。是的,我必須知道哪一個元素号。是以我終止了重寫這個循環,相當頻繁……

ROBERT HESS: 噢,真的嗎?

JEFFREY RICHTER: 是真的。

ROBERT HESS: 當作一個标準的For循環?

JEFFREY RICHTER:對,當作一個标準的For循環。是以有時到了最後,它所做工作比我當初想象的還要多。使用foreach是相當常見的,有了它實在是很爽。

ROBERT HESS:我猜您本來也應當在那裡放置一個計數器,不過這會完全使foreach不起作用。

JEFFREY RICHTER: 是的,很正确。

ROBERT HESS:那麼,您認為C#還另外具有什麼樣很酷特性,以讓觀衆說,好,這就是我要選的語言?

JEFFREY RICHTER:嗯,正如Anders在前面指出,C#是完全基于元件的,在那裡具有事件,具有接口,具有屬性,它們都是一等公民,是以沒有下滑杠,沒有下滑杠屬性等任何類似的東西。出身于C#的人應當熟悉異常處理,因為遇到錯誤時,就調用在基類庫中的framework裡的錯誤處理程式。是以我在螢幕上寫了一小塊代碼,以示範如何進行适當的錯誤處理。我具有一個try語塊,再強調一下,您應注意在try這個單詞的前面沒有下滑杠,因為在C#語言中它位于第一階層。我new一個檔案流對象,這是打開磁盤裡的檔案的一種方式。而在雙引号裡,我給出了我們希望打開的檔案的路徑名。

using System;

using System.IO;

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:等等,那是一個錯誤,是嗎?

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#的應用程式時,您必須保證函數和方法都能正确地設定異常并抛出一個異常,以便人們可以捕獲它?

JEFFREY RICHTER:嗯,絕對如此。良好的程式設計典範規定:當編寫一個函數時,必須驗證所有傳遞進來的參數,如果任何一個參數不合乎要求,就應當明确地引發一個異常,而在基類庫中定義有大量的異常類,是以可以輕而易舉地使用其中的一個。但是您同樣也有能力定義自己的異常類,或許,要查找資料庫中的、顧客(customer),卻好象沒有發現他們的名字,故可以建立自己的customer異常,并在代碼裡的某個地方引發它。

ROBERT HESS:或許會用類似customer的名字作為損壞的customer名……

JEFFREY RICHTER:是的,大概這樣。如果它是"Robert",就是你一直想要引發的異常。

ROBERT HESS:那麼,您認為C#作為一種程式設計語言将如何發展?當您的客戶參加教育訓練時您對他們有什麼點撥,他們對此又有什麼想法?

JEFFREY RICHTER:嗯,我真的認為它将獲得巨大的動力。我說過,去年我一直專門用C#程式設計,偶爾也用C++,但現在卻很少用了,而我相信許多VB程式員也将會轉向此語言,因為C#更适合公共語言運作庫。是以,我真的認為它将獲得巨大的動力,并且真正得到重用。在我的教育訓練班裡,似乎每個人都喜歡它,事實上一些人說他們參加這個教育訓練班,隻是由于這個班開設了C#程式設計的課,但很快他們就高興地發現課程也涵蓋了framework和類庫。

ROBERT HESS:那麼,當談到.NET framework和類庫時,您認為它們怎麼樣,以及它們是怎樣幫助應用程式開發的?

JEFFREY RICHTER:我認為,這個平台表現很出色。我使用整個平台已經一年了,并且我最近一直在為微軟開發一個項目,以展示微軟的許多技術。我和另外一個家夥一起工作,他的名字叫Tom,我們要在早上碰頭,要在電子白闆上繼續讨論,接着要…… 這裡就是我們今天将要補充說明的性能,我們又要讨論一會兒,我們要表示,這就是當天結束時我們的目标,通常在午飯之前我們要全部完工。我們總是超額地完成了任務。

ROBERT HESS:您認為C#和.NET的結合有助于完成工作嗎?

JEFFREY RICHTER: 噢,當然。毫無疑問,因為所有的測試都已完成。所有的測試——我們如何公開這個東西,我們能不能使這成為一個方法,能不能把它放在DLL裡,能不能使其成變COM 對象,我們應擁有什麼類型的接口。所有的這些問題涉及到您如何把這些連接配接起來并傳遞指針,保持連接配接以便可以同步,是以您就可以通過保持和其他人同步來通知他們,所有這些論點都剛剛被引進該平台。是以,自始至終地,我們願意工作一個小時,我們要完成某項工作,我們會……,然後我們又要坐回去并開始增加其它的東西。我們的生産率如何,确實令人難于置信,而且也同樣充滿着樂趣。我們确實增加了驚人的圖形圖像庫和alpha混色(blending)以及所有類型的東西,這些以前我們從未處理過alpha混色此類東西。我曾經從事過圖形圖像的工作,但已經過了好多年了。而利用相應名字空間中的system.drawing語句,我們就能夠構造這些圖像并對它們進行覆寫和alpha混色,然後又從我們的web伺服器傳回這些圖像給在任何機器上運作的任一客戶,甚至不必是一台Windows機器。

ROBERT HESS:我想這帶來了有利的選擇。迄今為止,我們一直在談論用C#和.NET framework等進行應用程式的開發,并且我了解到您原來就是一個貨真價實的應用程式設計師,編寫Windows應用程式和标準的GUI程式。令人意外的是web出現了,是以每個人都想到編寫web應用程式,或編寫運作在浏覽器内部基于HTML的應用程式。但現在以一句話對您的産品進行概括,您正在談到具有這種alpha合成标準的Windows圖形應用程式,也談到了通路web并以相應的格式傳回給其它系統。那麼象您我這樣的Win32應用程式開發者,對傳統的應用程式開發環境以及新的web應用程式與.NET的混合有什麼看法?

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:使用alpha混色。

JEFFREY RICHTER:嗯,對,使用alpha混色。于是,這些資訊被送回web窗體,送回運作在任何機器上的客戶。我們甚至可以增加這樣的功能,當滑鼠移到某東西上方時,提示工具将會顯現并告訴您該網頁上相應的學校名和醫院名。此範例功能之強大,簡直令人無法相信。事實上客戶可以是運作任何作業系統的任何機器,并且我們在伺服器端利用Windows 2000的GDI+性能處理alpha混色,以及此類進階圖形操作,不過我們隻把位圖(bit map)送回給客戶,我再次認為,其功能之強大、生産率之高,簡直令人信難于置信。而且我也了解到許多應用正在朝這個方向發展。

ROBERT HESS:是以您真的很喜歡web應用程式的整個web模型。

JEFFREY RICHTER: 喜歡。

 ROBERT HESS:即使您是一個傳統的Windows應用程式開發者。

JEFFREY RICHTER: 是的。

ROBERT HESS:您現在已橫下心來要朝這個方向發展了。

JEFFREY RICHTER:是的,我已下決心了。程式要能在任何地方運作,并在伺服器上進行工作。所有的這些便構成了所謂的分布式系統(distributedness),伺服器可以位于三台不同的機器,噢,維護所有的這些資料的SQL Server還可以是另一台機器,web 窗體伺服器也位于不同的機器,并且還可以被不同的公司細調以便随意使用這些材料,他們覺得這些材料适合于生成内容豐富的應用程式,而這些程式運作在能被internet通路到的任何地方。這簡直令人難于置信,确實難于置信!

ROBERT HESS:某些迹象告訴我,所有的這些東西給您留下了現象。

JEFFREY RICHTER:是的,有點。

ROBERT HESS:那麼,對于觀衆中躍躍欲試的開發人員,他們想要投身于C#,并要開始編寫一些.NET應用程式,在他們跨出第一步之前,需要真正地了解什麼?您認為最後還有什麼要強調的?

JEFFREY RICHTER:我認為,這些開發人員即将面臨的一個最大問題就是,他們必須認識到是C#語言揭示了runtime和基類庫中的性能,或許假以時日他們會從經驗中學到。而許多人将會關注C#,也可能他們會試一試,或關注其它的.NET語言,也有可能會企圖做一些不被這些語言所支援的事,接着當然認為這是不可能的。例如:在C#中,所有的數組預設都是基于0的,是以0索引(下标)開始的。但是公共語言運作庫支援數組有任何的下邊界和上邊界。在基類庫中構造了一個數組,它具有所設定的上下邊界。但是C#自然不提供這些功能。是以,您必須去學習,随着時間的推移,就會了解它是什麼,很多時候您或許可以使用其它語言,或者去通路語言的底層系統,語言是位于runtime頂端的,由于某些原因,設計者不讓我們去通路底層系統。

ROBERT HESS:似乎就是這樣,通過了解runtime底層的所有性能,然後您就可以把這些性能映射(map)給您目前正在使用的任何語言,以便了解它們是否提供給您所需要的功能。例如,我寫網頁時總是用純粹的HTML編寫,因為我知道它的具體功能是什麼。但是假如我必須用FrontPage寫,我知道FrontPage有它自己的格式(mindset),關系到網頁的顯示,并且我知道它能給我提供什麼,不能提供什麼。偶爾我也不得不轉回純粹的HTML并按這種方式增加某些東西或其它工具,這似乎是同樣的事情。

JEFFREY RICHTER:有時在C#中也有這些功能,但卻以不同的名字出現,例如,在公式語言庫中,虛拟函數被稱為family 。于是要在C#中建立一個虛拟函數,就會用protected 限定。對,或不用protected,但是在C#中的protected是等價于公共語言運作庫中的family的。噢,搞混了。看看,連我自己也糊塗了。

ROBERT HESS:是以基本的思路聽起來好象就是要去了解您正在使用的工具,以及它們在.NET framework底層的運作情況。好了,非常感謝Jeffery,又與您交談我感到非常榮幸,以後我會找一個時間再次邀請您回來參加這個“show”節目的。

JEFFREY RICHTER:好,我很樂意,謝謝。

ROBERT HESS:這就是程式員Jeffery對C#和.NET framework的看法。他提供給你們一些好資料,以讓你們了解更新的開發領域。他講到了很多的URL位址和源代碼例子以及類似的資料。我保證把它們放在本記錄稿的後面,是以請繼續觀看其餘的“show”節目,看看還有什麼内容。

……(略去與C#無關的談話)

 結束語

ROBERT HESS:謝謝您參加另一期的MSDN Show。這一次我們讨論了用C#程式設計的問題。

ERICA WIECHERS:在下一期的MSDN Show節目裡,我們将談論SOAP以及它是如何被整合到.NET程式設計體系的。

ROBERT HESS: 到那時,我們再在網上見面。

更多資料的連結

Microsoft C#資料:

C#綜述和介紹(Overview and Introduction to C#,http://msdn.microsoft.com/vstudio/nextgen/technology/csharpintro.asp)

C#語言規範(C# Language Specification,http://spectre/test/library/default.asp?URL=/library/dotnet/csspec/vclrfcsharpspec_Start.htm)

MSDN之聲:深入C#專欄(MSDN Voices: Deep C# column,http://msdn.microsoft.com/voices/deepc.asp)

    一個定期的專欄,在這裡Bobby Schmidt分享他使用C#的觀點和見識。

MSDN .NET開發者中心(MSDN Developer Center for .NET,http://msdn.microsoft.com/net/)

     提供更多有關.NET技術的開發資料。

C#新聞討論區(C# Newsgroup,news://msnews.microsoft.com/microsoft.public.dotnet.languages.csharp)

與正在學習使用C#的人互相讨論、互相請教。

有關Jeffrey Richter談話的資料:

代碼範例(Sample Code:位址不詳)

書: Programming Applications for Microsoft Windows

     Programming Server-Side Applications for Windows

(和Jason Clark合寫)

Wintellect(http://www.wintellect.com/,)

Jeffrey 的教育訓練和咨詢公司。

TerraServer.NET(http://terraserver.microsoft.net/)

Jeffrey幫助編寫的mapping服務。

Jeffrey Richter的首頁(http://www.jeffreyrichter.com/)