[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# 中有兩種類型: > 參考類型和實值類型。 **參考類型**的變數會儲存期資料 (物件) 的參考,而**實值類型**的變數則會直接包含其資料。 **使用參考類型**時,這兩種變數可以參考相同的物件,因此對其中一個變數進行的作業可能會影響另一個變數所參考的物件。**用實值型別**時,每個變數都有自己的資料複本,因此對某一個變數進行的作業,不可能會影響其他變數[name=Microsoft Documents] - **實值型別(value type)**: 如常用的[內建資料型別](https://docs.microsoft.com/zh-tw/dotnet/csharp/language-reference/keywords/built-in-types-table),例如: `int`、`float`、`bool`都是實值型別 **(`object`和`string`除外)**。簡而言之,我們在使用這些實值型別時,例如**傳遞參數**,是**複製**一份相同的資料後,再對資料進行處理。 - **參考型別(reference type)**: 對參考型別進行操作的時候,是直接對**記憶體的位置**。進行處理。例如: 上述除外的`object`和`string`都是參考型別。 簡述Memory Allocation --- 根據型別的不同,C#會將他們配進不同的**記憶體位置中** - 實值型別的會被配置在Stack中。例如在使用方法**傳遞參數**時,若沒有使用`ref`或`out`等關鍵字,參數便會是實值型別。 - 參考型別會被配置在Heap中,實例化(或是說`new`)出來的`class`,就會被配在Heap,而那些`class`裏頭**實值型別**的變數成員,也會是該`class`的一員,配置在Heap中。 ref & out --- 上頭有句話: > ==在使用方法**傳遞參數**時,若沒有使用`ref`或`out`等關鍵字,參數便會是實值型別。== 若想傳入參數的**記憶體位置**可以在參數前面加上`ref`或`out`。 這兩個關鍵字的差別在於: 1. `ref`在傳入方法之前**必須**初始化。 2. `out`在傳入方法之前**不必**初始化,但必須在方法內**指派值**才可回傳。 #### 題外話 ```C#= public void ChangeValue(ref int num) { // Do Something } public void ChangeValue(out int num) { // Do Something } ``` > 這兩個不會進行overloading,因為參數傳遞的方式都是傳參考,compiler無法辨識。 參考資料 --- >* [Struct V.S Class 兩者之間差異](https://dotblogs.com.tw/daniel/2018/02/22/135011) >* [[C#] Value Type (實值型別) vs. Reference Type (參考型別)](https://dotblogs.com.tw/miolovemiffy/2018/06/28/142221) >* [參考類型 (C# 參考)](https://docs.microsoft.com/zh-tw/dotnet/csharp/language-reference/keywords/reference-types) >* [[C#][筆記] Value Type (實值型別) vs. Reference Type (參考型別)](http://xingulin.tumblr.com/post/48493582986/ref-type-vs-val-type)