轉貼:msdn 訪談錄之C#編程三

來源:互聯網
上載者:User
編程 標題     msdn 訪談錄之C#編程    rainbow(翻譯)關鍵字    C#,JEFFREY RICHTER出處    http://www.mdsn.com[TR]

程式員天地
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: 是真的。



相關文章

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 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。