Try   HackMD

[C#]class vs. struct與Reference Type與Value Type

tags: C# Programming

比較

class struct
繼承(inheritance) 可以 不可以
介面(interface) 可以 可以
NULL 可以為null 不可以為null
型態 參考型態(reference type) 實值型態(value type)
Memory Allocation Heap Stack

實值與參考

C# 中有兩種類型:
參考類型和實值類型。 參考類型的變數會儲存期資料 (物件) 的參考,而實值類型的變數則會直接包含其資料。 使用參考類型時,這兩種變數可以參考相同的物件,因此對其中一個變數進行的作業可能會影響另一個變數所參考的物件。用實值型別時,每個變數都有自己的資料複本,因此對某一個變數進行的作業,不可能會影響其他變數Microsoft Documents

  • 實值型別(value type): 如常用的內建資料型別,例如: intfloatbool都是實值型別 (objectstring除外)。簡而言之,我們在使用這些實值型別時,例如傳遞參數,是複製一份相同的資料後,再對資料進行處理。

  • 參考型別(reference type): 對參考型別進行操作的時候,是直接對記憶體的位置。進行處理。例如: 上述除外的objectstring都是參考型別。

簡述Memory Allocation

根據型別的不同,C#會將他們配進不同的記憶體位置中

  • 實值型別的會被配置在Stack中。例如在使用方法傳遞參數時,若沒有使用refout等關鍵字,參數便會是實值型別。
  • 參考型別會被配置在Heap中,實例化(或是說new)出來的class,就會被配在Heap,而那些class裏頭實值型別的變數成員,也會是該class的一員,配置在Heap中。

ref & out

上頭有句話:

在使用方法傳遞參數時,若沒有使用refout等關鍵字,參數便會是實值型別。

若想傳入參數的記憶體位置可以在參數前面加上refout

這兩個關鍵字的差別在於:

  1. ref在傳入方法之前必須初始化。
  2. out在傳入方法之前不必初始化,但必須在方法內指派值才可回傳。

題外話

public void ChangeValue(ref int num) { // Do Something } public void ChangeValue(out int num) { // Do Something }

這兩個不會進行overloading,因為參數傳遞的方式都是傳參考,compiler無法辨識。

參考資料