首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 淺層複製與深層複製 (一) - 核心概念與記憶體模型

     編輯:關於C語言

C# 型別系統分為 **值型別** 與 **參考型別**,理解兩者在記憶體中的配置與複製語意,是掌握淺/深層複製的基石。

型別分類

類別包含型別記憶體配置
值型別struct、enum、基本型別 (int, double, bool, char...)、Tuple (C# 7+)堆疊 (區域變數) / 內嵌於物件
參考型別class、interface、delegate、array、string、object堆積 (物件本體) + 堆疊/內嵌 (參考指標)

記憶體模型圖解

值型別 (int a = 10; int b = a;)
棧: [a: 10] [b: 10]  ← 獨立副本,互不影響

參考型別 (Person p1 = new Person(); Person p2 = p1;)
棧: [p1: 0x1000] [p2: 0x1000]  → 指向同一堆積物件
堆: [0x1000] Person { Name = "Tom", Age = 20 }

複製分類定義

複製類型值型別欄位參考型別欄位適用場景
淺層複製逐位複製 (獨立)複製參考 (共用實例)單層物件、無可變參考、效能優先
深層複製逐位複製 (獨立)遞迴建立新實例並複製內容 (完全獨立)複雜物件圖、需完全隔離、序列化/備份

實作機制

  • 淺層複製:`Object.MemberwiseClone()` (protected) → 公開包裝 `Clone()` 方法。
  • 深層複製三大主流:
    1. 序列化/反序列化:`BinaryFormatter` (已淘汰)、`JsonSerializer`、`XmlSerializer`、`Protobuf`、`MessagePack`。需型別可序列化 (`[Serializable]` 或無參建構函式)。
    2. 反射遞迴:遍歷所有欄位/屬性,值型別直接複製,參考型別遞迴 `Activator.CreateInstance` + 複製。可控制排除/包含邏輯 (Attribute 標記)。
    3. 手動實作:每個類別實作 `DeepClone()` 明確 `new` 子物件並複製欄位。最快、最可控、但維護成本高。

ICloneable 介面爭議

.NET 文件明確建議 **不要** 公開實作 `ICloneable`,因其未定義淺/深層語意,導致呼叫端無法預期行為。建議自訂介面:


public interface IDeepCloneable { T DeepClone(); }
public interface IShallowCloneable { T ShallowClone(); }

常見陷阱

  1. 字串看似參考型別但表現如值型別:不可變,重新指派不影響原變數。
  2. 集合淺層複製:`list.ToArray()`、`new List(list)` 僅複製參考,元素物件仍共用。
  3. 事件/委派欄位:淺層複製會複製委派鏈,導致事件處理器重複觸發或洩漏,深層複製通常需清空事件。
  4. 循環參考:深層複製遞迴需維護 `Dictionary` 已複製映射表防無限遞迴。

下一篇將展示 `MemberwiseClone` 淺層複製完整程式碼與行為驗證。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved