前篇中也是老趙面試題的第一題,這篇繼續,希望通過這些面試題來找到我們學習的重點,而不是背這些東西,希望以這些個點來系統的去學習.net.
類(class)和結構(struct)的區別是什嗎?它們對效能有影響嗎?.NET BCL裡有哪些是類(結構),為什麼它們不是結構(類)?在自訂類型時,您如何選擇是類還是結構?
先看MSDN上的C# 語言規範上的定義:
類和結構是 .NET Framework 中的常規類型系統的兩種基本構造。兩者在本質上都屬於資料結構,封裝著一組整體作為一個邏輯單位的資料和行為。資料和行為是該類或結構的“成員”,它們包含各自的方法、屬性和事件等.
類或結構的聲明類似於藍圖,用於在運行時建立執行個體或對象。如果定義一個名為 Person 的類或結構,則 Person 為類型名稱。如果聲明並初始化 Person 類型的變數 p,則 p 稱為 Person 的對象或執行個體。可以建立同一 Person 類型的多個執行個體,每個執行個體在其屬性和欄位中具有不同的值。
類是一種“參考型別”。建立類的對象時,對象賦值到的變數只儲存對該記憶體的引用。將對象引用賦給新變數時,新變數引用的是原始對象。通過一個變數做出的更改將反映在另一個變數中,因為兩者引用同一資料。
結構是一種實值型別。建立結構時,結構賦值到的變數儲存該結構的實際資料。將結構賦給新變數時,將複製該結構。因此,新變數和原始變數包含同一資料的兩個不同的副本。對一個副本的更改不影響另一個副本。
類通常用於對較為複雜的行為建模,或對要在建立類對象後進行修改的資料建模。結構最適合一些小型資料結構,這些資料結構包含的資料以建立結構後不修改的資料為主。
結構與類共用大多數相同的文法,但結構比類受到的限制更多
- 在結構聲明中,除非欄位被聲明為 const 或 static,否則無法初始化。
結構不能聲明預設建構函式(沒有參數的建構函式)或解構函式。
結構在賦值時進行複製。
將結構賦值給新變數時,將複製所有資料,並且對新副本所做的任何修改不會更改原始副本的資料。在使用實值型別的集合(如
Dictionary<string, myStruct>)時,請務必記住這一點。
結構是實值型別,而類是參考型別。
與類不同,結構的執行個體化可以不使用 new 運算子。
結構可以聲明帶參數的建構函式。
一個結構不能從另一個結構或類繼承,而且不能作為一個類的基。
所有結構都直接繼承自 System.ValueType,後者繼承自 System.Object。(其實就是實值型別與參考型別的區別)
結構可以實現介面。
結構可用作可為 Null 的型別,因而可向其賦 null 值。
.NET BCL裡有哪些是類(結構),為什麼它們不是結構(類)?BCL(Base
Class Library)是Dot Net Framework下所有語言使用的類庫(有哪些類和結構,你就隨便說吧,System名字空間的有多少啊~需要注意的是DateTime這玩意其實是一個結構體。)為什麼他們不是結構(類)呢?這道題和下面的小問題其實是一個問題那就是什麼時候定義結構什麼時候定義類,下面一起回答在自訂類型時,您如何選擇是類還是結構?
struct 類型適於表示 Point、Rectangle 和 Color 等輕量對象。儘管使用自動實作屬性將一個點表示為類同樣方便,但在某些情況下使用結構更加有效。例如,如果聲明一個
1000 個 Point 對象組成的數組,為了引用每個對象,則需分配更多記憶體;這種情況下,使用結構可以節約資源。因為
.NET Framework 包含一個名為 Point 的對象,所以本樣本中的結構命名為“CoOrds”。複數、座標系中的點或字典中的“鍵-值”對都是結構的典型樣本。
除非滿足一下所有條件,否則不要定義成實值型別(結構體) 第一,類型具有基元類型的行為。類型簡單,其中沒有成員會修改類型的任何執行個體欄位。 第二,類型不需要從其他任何類型繼承。 第三,類型不會派生出其他任何類型。 除了滿足以上全部條件,還必須滿足以下條件中的一個。 第一,類型的執行個體較小(約是16位元組或者更小)。 第二,類型執行個體較大,但不作為方法的實參傳遞,也不通過方法返回。