類和結構

王明輝發表於2014-06-19

類和結構(C# 程式設計指南)

類和結構是 .NET Framework 中的常規型別系統的兩種基本構造。 兩者在本質上都屬於資料結構,封裝著一組整體作為一個邏輯單位的資料和行為。 資料和行為是該類或結構的“成員”,它們包含各自的方法、屬性和事件等(本主題後面列出了這些內容)。

類或結構的宣告類似於藍圖,用於在執行時建立例項或物件。 如果定義一個名為 Person 的類或結構,則 Person 為型別名稱。 如果宣告並初始化 Person 型別的變數 p,則 p 稱為 Person 的物件或例項。 可以建立同一 Person 型別的多個例項,每個例項在其屬性和欄位中具有不同的值。

類是一種“引用型別”。 建立類的物件時,物件賦值到的變數只儲存對該記憶體的引用。 將物件引用賦給新變數時,新變數引用的是原始物件。 通過一個變數做出的更改將反映在另一個變數中,因為兩者引用同一資料。

結構是一種值型別。 建立結構時,結構賦值到的變數儲存該結構的實際資料。 將結構賦給新變數時,將複製該結構。 因此,新變數和原始變數包含同一資料的兩個不同的副本。 對一個副本的更改不影響另一個副本。

類通常用於對較為複雜的行為建模,或對要在建立類物件後進行修改的資料建模。 結構最適合一些小型資料結構,這些資料結構包含的資料以建立結構後不修改的資料為主。

http://msdn.microsoft.com/zh-cn/library/ms173109.aspx

結構(C# 程式設計指南)

結構與類共享大多數相同的語法,但結構比類受到的限制更多:

  • 在結構宣告中,除非欄位被宣告為 const 或 static,否則無法初始化。

  • 結構不能宣告預設建構函式(沒有引數的建構函式)或解構函式。

  • 結構在賦值時進行復制。 將結構賦值給新變數時,將複製所有資料,並且對新副本所做的任何修改不會更改原始副本的資料。 在使用值型別的集合(如 Dictionary<string, myStruct>)時,請務必記住這一點。

  • 結構是值型別,而類是引用型別。

  • 與類不同,結構的例項化可以不使用 new 運算子。

  • 結構可以宣告帶引數的建構函式。

  • 一個結構不能從另一個結構或類繼承,而且不能作為一個類的基。 所有結構都直接繼承自 System.ValueType,後者繼承自 System.Object。

  • 結構可以實現介面。

  • 結構可用作可以為 null 的型別,因而可向其賦 null 值。

http://msdn.microsoft.com/zh-cn/library/saxz13w4.aspx

使用結構(C# 程式設計指南)

struct 型別適於表示 Point、Rectangle 和 Color 等輕量物件。 儘管使用自動實現的屬性將一個點表示為同樣方便,但在某些情況下使用結構更加有效。 例如,如果宣告一個 1000 個 Point 物件組成的陣列,為了引用每個物件,則需分配更多記憶體;這種情況下,使用結構可以節約資源。

 

為結構定義預設(無引數)建構函式是錯誤的。 在結構體中初始化例項欄位也是錯誤的。 只能通過兩種方式初始化結構成員:一是使用引數化建構函式,二是在宣告結構後分別訪問成員。 對於任何私有成員或以其他方式設定為不可訪問的成員,只能在建構函式中進行初始化。

如果使用 new 運算子建立結構物件,則會建立該結構物件,並呼叫適當的建構函式。 與類不同,結構的例項化可以不使用 new 運算子。 在此情況下不存在建構函式呼叫,因而可以提高分配效率。 但是,在初始化所有欄位之前,欄位將保持未賦值狀態且物件不可用。

當結構包含引用型別作為成員時,必須顯式呼叫該成員的預設建構函式,否則該成員將保持未賦值狀態且該結構不可用。 (這將導致編譯器錯誤 CS0171。)

對於結構,不像類那樣存在繼承。 一個結構不能從另一個結構或類繼承,而且不能作為一個類的基。 但是,結構從基類 Object 繼承。 結構可實現介面,其方式同類完全一樣。

無法使用 struct 關鍵字宣告類。 在 C# 中,類與結構在語義上是不同的。 結構是值型別,而類是引用型別。 有關更多資訊,請參見值型別

除非需要引用型別語義,將較小的類宣告為結構,可以提高系統的處理效率。

 

相關文章