C#面試考題解答篇-1

前情提要:原文連結
上一篇文章公布了某公司的C#面試考題,現在就來寫個解答篇~
Q1.C#型別系統(C# typing system)包含哪幾種?(不是在問資料類型,如:int、string...)
差異為何?
各舉一項資料類型。




Ans:
1:實質型別、參考型別、指標型別。
2.差異:
實質型別:直接儲存值
參考型別:視為物件,指向記憶體中的Heap
指標型別:只能用於unsafe模式。將指向另一個記憶體位置當作是一種型別的型別
3.舉例
實質型別:int
參考型別:所有的物件都是參考型別
指標型別:列舉(Enum)


實質型別詳細解說:

MSDN:
直接以實值型別為基礎的變數,可包含值。指派一個實值型別變數給其他實值型別變數,會複製所包含的值。這和參考型別變數的指派不同,參考型別變數的指派會複製物件的參考,但不會複製物件本身。
所有實值型別都是自 System.ValueType 隱含衍生而來。
不同於參考型別,您可以從實值型別衍生新型別。然而,就像參考型別,結構可以實作介面。
不同於參考型別,實值型別不可包含 null 值。不過,可為 Null 的型別功能允許將實值型別指派為 null
每個實值型別都有隱含預設建構函式 (Constructor),來初始化此種型別的預設值。如需實值型別預設值的詳細資訊,請參閱預設值表
實質型別是直接把值(含類型)直接存放在記憶體的某一個位置,當你把一個變數宣告成實質型別,你也就把變數的類型跟值都放在一個記憶體位置。.

參考型別詳細解說:

MSDN:
參考類型的變數會儲存期資料 (物件) 的參考,而實值類型的變數則會直接包含其資料。 使用參考類型時,這兩種變數可以參考相同的物件,因此對其中一個變數進行的作業可能會影響另一個變數所參考的物件。 使用實值類型時,每個變數都有自己的資料複本,因此在某一個變數上進行的作業不可能會影響其他變數 (但 ref 和 out 參數除外),請參閱 ref 和 out 參數修飾詞

白話文一點,實值型別 (Value Type) 的變數會儲存資料,而參考型別 (Reference Type) 的變數則儲存實際資料的參考,所以當兩種型別在做指派動作時,兩個雖然指派的動作邏輯一樣,實際上結果卻是不同的,舉例來說:
我定義一個參考型別,如下圖
再定義一個實質行型別,如下圖

然後執行以下程式,如下圖:

為什麼會這樣??為什麼第一組的參考型別的值也被改變了??是Bug嗎??還是業障重??

當然不是!!
第二組實質型別在指派時,是將第一組的「值」複製給第二組。
但第二組參考型別在指派時,是將第一組的「Heap的記憶體位置」複製給第二組。
所以了解為什麼了嗎?

參考型別詳細解說:

MSDN:
在 unsafe 內容中,類型有可能是指標類型、實值類型或參考類型。 指標類型宣告會使用下列其中一種格式:

type* identifier;  
void* identifier; //allowed but not recommended  
下列任何一種類型都可能是指標類型:
sbytebyteshortushortintuintlongulongcharfloatdoubledecimalbool
任何 enum 類型。
任何指標類型。
任何只包含 Unmanaged 類型欄位的使用者定義結構類型。
指標類型不會從 object 繼承,而且指標類型與 object 之間無法進行轉換。 此外,boxing 和 unboxing 不支援指標。 不過,不同的指標類型之間以及指標類型與整數類資料類型之間可以進行轉換。
我相信很多人都跟我一開始一樣看不懂,所以我先說明什麼是unsafe

unsafe

MSDN:
為了維護型別安全 (Type Safety) 和安全性,C# 預設不支援指標算術。 然而,藉由使用 unsafe 關鍵字,即可定義能在其中使用指標的 unsafe 內容。 如需指標的詳細資訊,請參閱指標型別主題。

在 Common Language Runtime (CLR) 中,Unsafe 程式碼稱為無法驗證的程式碼。 C# 中的 Unsafe 程式碼不一定具有危險性,只是它的安全性無法由 CLR 驗證。 因此,CLR 將只會執行位於完全受信任組件內部的 Unsafe 程式碼。 如果您使用 Unsafe 程式碼,請務必確認程式碼不會帶來安全性風險或造成指標錯誤。
所以說~這樣大家有沒有比較懂指標型別&unsafe在幹嘛了呢?
指標 (pointer) 就是儲存記憶體位址的資料型態 (data type),使用上要特別的小心,舉例來說,今天你指標指到了一個物件的記憶體位置,那個物件還是可以被回收掉的,那這時會發生什麼事?假設這記憶體位置被另外一個物件使用了,那這時又會發生什麼事情?
所以.... 因為可能會出很多你無法預期的奇怪問題,沒事少用就對了。

參考資料:MSDN

留言