從C#2.0的角度看.NET 2.0類型系統

來源:互聯網
上載者:User
C#中所有變數使用之前都必須初始化,否則編譯器會在初始化時產生一個編譯錯誤。

每個Windows線程都有一個私人的記憶體區塊,稱為棧;也就是說這塊記憶體塊不能被其他線程訪問(特定條件下除外)。什麼條件?
線程的棧主要用於:

  • 儲存正在執行中的方法的傳入實參值;
  • 儲存方法返回是需要跳轉的本地代碼的地址;
  • 儲存對象(但不是全部)。

一個進程通常只有(有時也可以有多個)堆,為其下的所有線程所共用。何時?
堆的優點是容量比棧大得多。為所有線程所共用。
棧的優點是速度比堆快。這主要源於專門訪問棧的IL指令,以及訪問棧上的元素無需同步。
因此,用堆來儲存大對象,用棧儲存小對象。。
C#中的實值型別的執行個體使用靜態分配(分配線上程棧上),而參考型別的執行個體則使用動態分配(分配在進程堆中)。

結構、枚舉是實值型別,委託是參考型別

如果某個類的執行個體有個實值型別的欄位,那麼該欄位會和類執行個體儲存在一起,即堆中。反過來,如果一個結構的欄位是參考型別,那麼參考型別的執行個體還是會儲存在堆中。

在C#中,求模運算也可以用於浮點數。
float a = 5.5f;
Console.WriteLine(a % 2.5);
螢幕上將輸出0.5。
C#語言提供了checked關鍵字,可以得到驗證所有的類型轉換和運算。如果有問題就會引發一個異常。

整形和decimal類型被零除時,會產生DivideByZeroException異常。
浮點型float和double被零除時,會得到無窮大,0/0得到Nan。

C#的遞增和遞減運算子也可以用於浮點數。
float a = 5.5f;
a++;
此時a = 6.5。

C#中的結構不能從其他類或者結構派生,也不能作為其他類型或結構的基類。
C#的結構可以有多個建構函式,當不允許自訂預設的建構函式(即沒有參數的建構函式)。而且編譯器要求每一個建構函式都初始化結構的所有欄位。
預設建構函式將所有實值型別的欄位設為零,而將所有參考型別的欄位設為空白引用。
結構可以有自己的方法。
與類的欄位不同,結構的欄位不能在聲明中顯示初始化。
結構的執行個體常常儲存在棧中,因此結構不宜太大。太大的結構最好用類代替。

編譯器預設情況下,將枚舉的值視為int型整數。因此,枚舉定義的這組常數中任意一個值都是一個整數。可以對其進行遞增、遞減操作。
在預設情況下,枚舉的第一個值是0,之後的每一個值都是前一個值加1.當然,也可以手工指定自己想要的值。
你也可以定義其他類型的枚舉類型的值:
    enum MakerCHB:byte{Beijing,Zhejiang}
    enum MakerCHL:long{Beijing,Zhejiang}

可以讓一個枚舉的執行個體包含多個枚舉值。這個概念也稱為二進位位標誌(binary flag)或者標誌枚舉(flag enum).
注意,位域枚舉都打上了System.Flags attribute標誌,該attribute通知CLR和用戶端這個枚舉用來表示位域而不是標準枚舉,這個枚舉用來表示位域而不是標準枚舉。這個標誌會影響ToString()方法的結果。最好能有個執行個體!
.NET Framework中的System.Threading.ThreadState就是採用了二進位標誌的枚舉。

C#中String類的執行個體是不可變。即無法修改它們,它們將保持通過建構函式所賦的值不變。
C#允許定義無轉義的字串字面常量,方法就是在字串起始的雙引號之前加入“@”符號。無逸出字元串字面常量具有以下特徵:

  • 它將接受所有字元作為字串的內容,包括“\”反斜線字元,不過不包括雙引號。
  • 它將接受字串中的所有換行。

C#是String類的執行個體是不可變的。使得對所有字串的修改操作均會分配一個新的String執行個體。如果應用程式要頻繁修改字串或者處理長字串,那麼更好的方法是使用System.Text.StringBuilder類。
通過不安全的程式碼也可以打破字串執行個體的不可變特性。

C#允許用delegate關鍵字建立一種特殊的類,我們稱這種類為委託類。委託類的執行個體稱為委派物件。
委派物件是一種指向一個或多個方法(靜態或非靜態)的引用。我們可以像調用方法那樣“調用”委派物件,這其實就是調用委派物件所引用的方法。注意這些方法的調用是在調用委託的方法所在的線程中完成的,即同步調用。
委託變數所能引用的方法只能是其簽名式與委託類聲明中所提供的簽名式一致的方法。delegate void Deleg1();
delegate string Deleg2(string s);
delegate void f1()
{
}
static string f2(string s)
{
}
Deleg1 d1 = new Deleg1(f1);   // right
Deleg2 d2 = new Deleg2(f2);   // right
Deleg2 d3 = new Deleg2(f1);   // error

C# 2.0編譯器引入在建立委託變數時推測其類型的功能。於是就可以直接將一個方法賦給隱式建立的對象。如
Deleg1 d1 = f1;
Deleg2 d2 = f2;
但是,其編譯產生的IL代碼,跟前面的是一樣的,它仍舊調用了Deleg1和Deleg2委託類的建構函式。
可以用一個委派物件應用多個具有相同簽名式的方法(靜態或非靜態)。這種情況下調用委派物件就會在調用對象的線程中順序執行所有的方法。調用方法的順序就是方法添加到委派物件中的順序,每個方法的參數都是一樣的。
如果委託的簽名具有傳回值,那麼引用多個方法時只有最後一個調用的方法的傳回值才作為委派物件的傳回值返回。
可以用GetInvocationList()擷取該委派物件中的委託列表。

可空類型System.Nullable<T>等價於T?。
    即int? i = null;和Nullable<int> i = null;是等價的。
不過,編譯器會阻止從可空類型到原始類型的隱式轉換。此外,不事先測試而進行可空類型到原始類型的顯示轉換也是危險的,因為,這可能會引發InvalidOperationException異常。

C# 2.0允許將類、結構和介面的聲明分散到多個源檔案中。我們稱這一特性命名為部分類型。注意,委託類或者枚舉類是不能聲明在多個源檔案中的。
同一個類型各個不同的部分定義前面必須都加partial關鍵字。而且,如果該類型是泛型的,那麼型別參數的定義也必須出現在每個部分的部分定義上。每個部分定義上型別參數的名稱和位置必須完全一致。即在每個部分什麼的class、struct或interface關鍵字之前加partial關鍵字。而且必須屬於同一個命名空間。

相關文章

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.