承接[上集](第八回),本文從語言規則、特殊類型、核心機制三維度,系統整理值/引用類型的比較規則、應用場景與易錯陷阱。
| 特性 | 值類型 | 引用類型 |
|---|---|---|
| 繼承鏈 | ValueType → Object | 直接繼承 Object |
| 記憶體 | 堆疊 (內含資料) | 堆 (變數存引用) |
| 指派 | 成員複製 (深拷貝) | 引用複製 (淺拷貝) |
| 參數傳遞 | 預設複製實例 | 預設複製引用 |
| Null | 不可為 null (C# 2.0 前) | 預設 null |
| 繼承 | 密封,不可繼承類別,可實作介面 | 可繼承、可多型 |
| GC | 不受管,作用域結束自動釋放 | GC 追蹤回收 |
| 裝箱 | 有裝箱/未裝箱兩種狀態 | 永遠是裝箱狀態 |
| sizeof | 支援 | 不支援 |
| 基元類型對應 | int→Int32, double→Double 等 | 無對應 |
string 繼承 Object 是引用類型,但:
s += "x") 實為建立新字串、舊字串不變void M(string s){ s="new"; } 外部原變數不變,因方法內 s 指向新物件"123" == "123" 為 true (內容相等),非引用相等本質原因:不可變性 + 運算子重載,而非特殊傳遞規則。參考 Artech《深入理解 string》獲取更多效能建議。
ArrayList.Add(3)) 產生大量臨時物件,增加 GC 壓力ValueType 重寫 Equals 實現值比較,解決裝箱後判等問題。
| 方法 | 值類型 | 引用類型 |
|---|---|---|
ReferenceEquals(a,b) | 永遠 false (雙重裝箱) | 同一實例 true;null==null true |
Equals(a,b) 靜態 | 處理 null,委派虛方法 | 同實例/同 null/虛方法 true |
a.Equals(b) 虛 | ValueType: 欄位逐一比較 | 預設引用比較,常重寫 |
a == b | 未重載則位元比較 | 預設引用比較,常重載 (如 string) |
最佳實踐:自訂類型務必重寫 Equals/GetHashCode,並考慮重載 ==/!=。
is/as:安全模式轉換,as 失敗回傳 nullConvert/Parse:字串↔基元類型implicit/explicit 運算子:需 static,定義類型間轉換規則優先考慮 struct 當:資料量小 (<16 bytes)、邏輯簡單、無繼承/多型需求、高頻建立/銷毀、需值語義安全。
必須用 class 當:需繼承、多型、複雜行為封裝、參考語義共享、頻繁裝箱場景 (改用 class 避免裝箱)。