C#是三大主流OOP(面向對象編程)語言(C++,Java,C#)之一,也是最新的一種,其中必然借鑒了前兩者的長處,“否則它的締造者就該打屁股”——候捷語,見《C#Primer中文版》的譯續:-)它們三者有太多的共性,其語法和編程概念,絕大部分彼此兼容,精一而通三。尤其對熟練掌握C++的程序員而言,學習Java和C#沒有任何難度,唯一需要花些時間的地方就是熟悉這二者的類庫。
三者中,C++是我最熟悉也最喜歡的,在學習C#時難免會將其與C++做對比,現將C#與C++的區別做一番小結。這是我花了大概三個小時看完《C#Primer中文版》的前兩章的心得,難免回有不少錯誤和偏差,暫且記下,以后糾正。
1、 C#與Java類似,編譯后得到的還不是機器代碼,而是運行在虛擬機中的元指令。它對安全性做了更多的考慮,沒有指針,不能直接操作內存,自動實現內存管理。C++中的指針在帶來強大的靈活性和高效的同時,也帶了不少使用上的難題,C++程序中的絕大多數問題都來源於指針的不正確使用,C#出於軟件安全性的考慮和語言易用性的考慮沒有指針。
C#中實現自動垃圾回收,通過new在堆中創建對象,當對該對象的引用計數為0時回收內存。類有構造函數而沒有析夠函數。
C#沒有指針這個概念,只有引用和數值之分。int等內部數據類型和struct定義的類型是數據類型,拷貝時做深度拷貝;而string和用class定義的類型是引用類型,拷貝時做淺拷貝——與深度拷貝對應,它通過引用計數來實現對象和內存管理。
C++中用指針能夠輕易實現的功能,C#需要引進許多額外的機制。比如C++的函數指針,在C#中稱之為delegate。C#中的參數傳遞,分為傳值和傳址兩種,傳址時需要加ref或者out(傳回改變)關鍵字。
C#中的const與C++中的有所不同,它指編譯期常量,而運行期間的常量要用readonly來指定。
2、 C#的OO特性更為徹底,一切皆對象,不存在獨立的函數,程序的入口Mai()函數是某個對象的public static成員函數。
所有對象都是由Object派生而來,包括內部數據類型int,float,string等,它們只是System.int32等的別名而已。C#中沒有模板,通過將參數設置為Object類型來實現類似的功能,它的downcast類似於C++中的dynamic_cast操作符。
C#沒有頭文件,變量、函數和類沒有定義和申明的區別,都在一起。只能通過設計抽象類的方式實現代碼分離。C++在這方面雖然做得還不夠完美,但比C#強不少。
C#中有屬性(Properties)和索引(Index)。屬性類似於C++中的那些GetValue()和SetValue()成員函數,只是使用上有些差別。索引類似於C++中的重載操作符[]。
C#中在類中的成員變量聲明處即可初始化,而C++中不行,兩者都可以在構造函數中初始化成員變量。C#中的靜態成員變量可以在靜態構造函數中初始化,而靜態構造函數是在該類的第一次使用時調用,而C++中是在編譯單元載入時初始化靜態成員變量。
3、 C#的語法中多了foreach(typevinlist)statement;而C++中需要用C++標准庫的函數實現類似功能。
C++相對C而言,引入了許多便於實現OOP的特性,也有出於軟件工程方面考慮的特性。許多C++程序員(包括我)深感它的博大精神。同時,它又繼承了C語言的簡介和優美,盡量用統一的風格實現盡可能多的特性,比如操作符重載、模板等。C#與C++相比較,更加復雜,還顯得臃腫和凌亂。
附:
- 1. C#不支持多重繼承,這是與C++明顯區別的地方,說真的多重繼承有時候用起來挺麻煩的,可能微軟怕你用不好吧,不給你提供了,但我個人覺得沒有了多重繼承感覺有點可惜。
- 2. 在標准的C#安全代碼中不支持指針類型的操作,然而,你卻能在微軟所謂的“非安全代碼”中操作指針類型對象。
- 3. C#中所有對象都只能通過關鍵詞“new”來創建,C++的“類名_對象名”方式在C#中變為聲明一個引用。呵呵,萬物皆對象,連常見的數據類型都變為對象了,JAVA味道很濃。
- 4. 數組變為了類,因此對於數組里的元素,.NETFramework直接提供了一系列的操作:查找、排序、倒置……
- 5. 在C#里面,數組的元素都是存放在托管堆里面,比起C++的在內存里不確定位置申請一塊連續空間要安全得多。
- 6. C++的switch后跟參數必須是int型,而C#卻允許string型,這點改進覺得真的是比以前方便多了!
- 7. C#會禁止所有switch..case語句的失敗情形,除非case語句后是空格,否則執行了前一個case語句就算沒有break也會停止執行后面的case語句。
- 8. 在異常處理上,C++允許拋出任何類型,而C#中規定拋出類型為一個派生於System.Exception的對象。
- 9. C++的宏在C#中被拋棄了很多,而且也不建議使用,因此很少見。
- 10. C++的模板在C#里沒有了,但在C#中我們找到了能完成模板任務的更鋒利的武器:委托。
- 11. C++的全局變量這一概念沒有了,C#和JAVA類似,要把所有東西都放在類里面,還建議使用命名空間包含起來。
- 12. C#可以在定義類的時候直接給屬性賦值,而C++這么做卻會編譯出錯。
- 13. C#里有靜態構造函數一個概念,這個構造函數只執行一次,因此能夠保證一些靜態成員只被初始化一遍。
- 14. C#有自動垃圾收集機制,防止內存泄露,把C++程序員從繁重的內存管理上解放出來。
- 15. 更強的類型轉換保護機制,比如說把float轉成uint,直接轉換0.35會變成0.34,是因為二進制無法表示這樣的數字,使用System.Conver里的方法,可以安全地把類型安全轉換過來。
- 16. 委托與事件、裝箱與取消裝箱、Web Services……一大堆C++沒有的新東西,我感覺是做大型項目方便了管理,也容易擴充,但做起小型項目,由於是編譯成IL代碼的,運行需要.NET Framework SDK支持,效率是個問題,不利於做那些對運算速度和內存消耗要求高的項目。