友快網

導航選單

# 程式碼生成# # 資料探勘# # 資料探勘# # 資料探勘# # 程式碼發生器#

部分類

C#使用部分類允許一個類的定義分割在幾個原始檔中。每一個部分必須用關鍵字partial標記。作為一個單一的彙編的部分所有的部分都必須提交給編譯器。每個部分可以引用其它部分的成員。每個部分都可以實現介面,並且某個部分可以定義一個基類。這個功能在程式碼生成時非常有用,也就是一個程式碼發生器提供一部分程式碼,開發商提供另一部分程式碼,兩種程式碼在一起編譯。因此開發商可以編輯他們的部分程式碼而不用冒著程式碼發生器在以後覆蓋這部分程式碼的危險。和類擴充套件機制不同,部分類在它的部分之間允許迴圈依賴,因為它們在編譯的時候都保證被解決。Java沒有類似的概念。

泛型

泛型程式設計

現在的程式語言都支援泛型程式設計,但它們卻採用了不同的實現方式。

Java中的泛型僅是語言層面上的一種結構,它們只能透過編譯器來實現。生成的類檔案中所包含的類簽名僅由元資料組成(允許編譯器對這些新類進行反編譯)。執行時並不知道通用型別系統,這意味著JVM只需要進行一小部分的更新便可處理新的類格式。

為了實現這個目標,編譯器用泛型型別的上界來替換它們,並且在用到這些泛型的各個地方適當地插入一些“角色”。結果生成的位元組碼將不包含任何對這些泛型型別的引用或將它們作為引數。這種實現泛型的技術被稱作型別擦除。這意味著實際上的型別的資訊在執行時不可用,並且強行加入了一些限制,例如不能建立泛型的新例項或陣列。(參見Java中的泛型)。

C#採用了另一種實現方式。它對泛型的支援是整合在虛擬執行系統中的,並且最早出現在。NET2。0中。這門語言後來就發展為在執行系統中支援基本泛型的前端。而在Java中,編譯器提供了靜態型別安全檢查,但是,加之又有即時編譯器(JIT)載入來核實其正確性。關於泛型型別的資訊在執行時完全被保護起來了,並且允許完全的反射和例項化泛型型別。

Java不允許用基本資料型別來宣告為泛型類,然而C#卻允許不管是引用型別還是值型別被宣告為泛型,包括基本資料型別。Java卻允許被封裝的型別作為泛型類的型別引數來使用(例如:用List代替List),但是由於所有這一類的值需要在堆上分配而需付出一定的“代價”。 在Java和C#兩者中,泛型的定義都使用了不同的引用型別來分享等效的底層程式碼,但是對C#來說公共語言執行時(CLR)為值型別的例項化動態的生成最佳化程式碼。

符號和特殊功能

特殊功能關鍵字

關鍵字 功能,例項

checked, unchecked 在C#裡, checked 宣告塊或表示式可以在執行時檢查算術的溢位。

get, set C#實現屬性作為語言語法的一部分,而且選用相應的get 和set 訪問器, 而Java的訪問方法, 不是一種語言功能,而是基於方法命名公約的編碼方式。

goto C#中支援goto關鍵字。goto有時候是有用的, 舉個例子,實現有限的狀態機或者生成的程式碼, 但是通常建議使用更加合理控制流程的結構化方法(見goto語句的評論)。 Java 允許使用breaks和continues彌補了goto語句的的許多用途。

switch(color)

{

case Color。Blue:

Console。WriteLine(“Color is blue”); break;

case Color。DarkBlue:

Console。WriteLine(“Color is dark”);

goto case Color。Blue;

// 。。。

}

out, ref C#支援輸出引數和引用引數。這使得c#可以從一個方法返回多個值或者透過引用傳遞多個值。

strictfp Java 使用關鍵字 strictfp 確保跨平臺時浮點運算的結果保持不變。

switch 在C#裡, switch 語句也操作於string型和long型,但是隻允許失敗的空白語句。 Java switch 語句在Java7之後才支援操作strings;不能操作於long 的原始型別 但是能透過所有的空白語句(不包括那些含有 ‘break’的語句)。

throws Java中要求每個方法都要宣告它能丟擲檢測異常或者檢測異常的父類。任何方法也可以隨意的定義它所丟擲的非檢測異常,C#中卻沒有這樣的語法規則。

public int readItem()throws java。io。IOException

{

// 。。。

}

using C#中的using指令使得物件的Dispose方法(透過IDisposable介面被執行)定義為在程式碼塊執行之後或者在程式碼塊之中的異常被丟擲時才被執行。

//建立一個小檔案“test。txt”,寫一個字串,

//。。。 並且把它關閉(即使發生了異常)

using (StreamWriter file = new StreamWriter(“test。txt”)) {     file。Write(“test”); }

yield C#語言中允許使用yield關鍵字來表示迭代器。在Java中,迭代器只能用類(可以是匿名的)來定義,且需要很多的樣板程式碼。下面是一個能夠讀取可迭代的輸入(可以是陣列)並且返回所有偶數成員的迭代器的例子。

public static IEnumerable GetEven(IEnumerable numbers)

{

foreach (int i in numbers)

{

if (i % 2 == 0)

yield return i;

}

}

回撥和事件處理

數值應用

多種語言特色的存在是為了充分的支援應用程式在數學和金融領域計算。[1]在這一類中,Java提供關鍵字strictfp可以在程式碼段中使浮點運算嚴格執行。這可以保證運算在所有的平臺上都返回相同精確的結果。 與此不同C#為確保十進位制小數浮點運算準確,在 decimal 型別中內嵌了這種機制。但在二進位制小數浮點運算中捨棄了這種機制(float, double)。 在二進位制所有的型別中描述十進位制數因為不精確會存在舍入誤差。所以在金融應用方面十進位制小數型別的精確顯得很重要。 Java中BigDecimal類也提供了這些特性。任意精度小數演算法 (BigDecimal) 和任意精度整數演算法 (BigInteger ) 的類為其提供任意精度的數值運算。 儘管有第三方實現了這些類,但是。NET框架(3。5)的現行版本當前並沒有提供這些。(參見Arbitrary-precision arithmetic) Java不能為庫定義型別(高精度小數、複數等原始型別)提供一個統一標準,為了達到這個目的,C#提供瞭如下內容:

能夠提供方便語法的運算子過載和索引(看下面)。

隱性和顯性轉換;允許諸如嵌入式int 型別隱性轉換為long型別的存在。

值型別和基於值型別的屬性;在Java中每個常規型別必須被存放在堆疊中,它對常規型別和儲存型別的效能是不利的。

除此之外,C#能用checked和unchecked運算子幫助數學計算,當在一段程式碼中出現算數溢位時它能夠檢測出是否能夠繼續執行。它也提供在內嵌陣列的某些應用方面有優勢的矩陣。

運算子過載

相比Java,C#包含了許多可數的便利。其中,例如運算子過載、使用者自定義型別,許多都被大批的C++程式設計師所熟悉。 它還具有“外在的成員實現”,這樣可以讓一個類明確的實現一個介面中的方法,與自己類中的方法分離。或者為分別來自兩個介面中,具有相同函式名和簽名的函式提供不同的實現。 C#包含了“索引器”,它可以當作是一種特殊的運算子(像C++中的operator[]),或者是用 get/set 訪問器來訪問類屬性。一個索引器用this[]來標明, 並且需要至少一個索引引數,該引數可以為任意類別:

myList[4] = 5; string name = xmlNode。Attributes[“name”];

orders = customerMap[theCustomer];

Java沒有提供運算子過載是為了阻止特徵濫用,還有為了語言的簡單。[2] C#允許運算子過載(以確定的幾個限制來確保邏輯上的一致為條件),如果小心地使用,可以使程式碼更加簡潔和易讀。

上一篇:蘋果公佈iphone 13渲染圖,這次的配色不香了,網友直呼:剛到手的iphone不香
下一篇:努比亞z30s評測:一款能讓你感受到極致的體驗的手機,你會買嗎?