C#中的深複製和淺複製(在C#中複製對象)

來源:互聯網
上載者:User

最近開發中對泛型資料進行排序,但是還需要用到未經處理資料,所以就複製了該對象到另一個對象,忘記了參考型別是傳地址的,所以出了bug,轉貼一篇文章,記錄一下自己的錯誤。

 

C# 支援兩種類型:“實值型別”和“參考型別”。
實值型別(Value Type)(如 char、int 和 float)、枚舉類型和結構類型。
參考型別(Reference Type) 包括類 (Class) 類型、介面類型、委託類型和數群組類型。

如何來劃分它們?
以它們在電腦記憶體中如何分配來劃分

實值型別與參考型別的區別?
1,實值型別的變數直接包含其資料,
2,參考型別的變數則儲存物件引用。
對於參考型別,兩個變數可能引用同一個對象,因此對一個變數的操作可能影響另一個變數所引用的對象。對於實值型別,每個變數都有自己的資料副本,對一個變數的操作不可能影響另一個變數。

實值型別隱式繼承自System.ValueType  所以不能顯示讓一個結構繼承一個類,C#不支援多繼承

堆棧(stack)是一種先進先出的資料結構,在記憶體中,變數會被分配在堆棧上來進行操作。
堆(heap)是用於為類型執行個體(對象)分配空間的記憶體地區,在堆上建立一個對象,
會將對象的地址傳給堆棧上的變數(反過來叫變數指向此對象,或者變數引用此對象)。

關於對象複製的所設計到知識點

淺拷貝:是指將對象中的所有欄位逐字複雜到一個新對象
        對實值型別欄位只是簡單的拷貝一個副本到目標對象,改變目標對象中實值型別欄位的值不會反映到原始對象中,因為拷貝的是副本
        對引用型欄位則是指拷貝他的一個引用到目標對象。改變目標對象中參考型別欄位的值它將反映到原始對象中,因為拷貝的是指向堆是上的一個地址

深拷貝:深拷貝與淺拷貝不同的是對於引用欄位的處理,深拷貝將會在新對象中建立一個新的對象和
        原始對象中對應欄位相同(內容相同)的欄位,也就是說這個引用和原始對象的引用是不同, 我們改變新
        對象中這個欄位的時候是不會影響到原始對象中對應欄位的內容。

淺複製: 實現淺複製需要使用Object類的MemberwiseClone方法用於建立一個淺表副本
深複製: 須實現 ICloneable介面中的Clone方法,且需要需要複製的對象加上[Serializable]特性

 

 

class DrawBase:System.Object , ICloneable
    {
        public string name = "jmj";
        public DrawBase()
        {
        }
       
        public object Clone()
        {
            return this as object;      //引用同一個對象
            return this.MemberwiseClone(); //淺複製
            return new DrawBase() as object;//深複製
        }
    }
class Program
{
 
        static void Main(string[] args)
        {
            DrawBase rect = new DrawBase();
            Console.WriteLine(rect.name);
            DrawBase line = rect.Clone() as DrawBase;
            line.name = "a9fs3";
            Console.WriteLine(rect.name);
            DrawBase ploy = line.Clone() as DrawBase;
            ploy.name = "lj";
            Console.WriteLine(rect.name);
 
            Console.WriteLine(object.ReferenceEquals(line, ploy));
            Console.ReadLine();
        }
}
運行結果:
 return this as object;      //引用同一個對象
輸出:jmj
        a9fs3
        lj
        True
 
return this.MemberwiseClone(); //淺複製
return new DrawBase() as object;//深複製
輸出均為: jmj
             jmj
             jmj
             False
解釋:
return this as object 方法總是引用同一個對象,因此相應的堆記憶體上的值會改變!
後兩種方法都是對對象的複製,區別在於複製的類別不同:深複製會複製整個填充的對象,包括該對象中其他參考型別和實值型別的值;而淺複製只複製了一個對象中所有引用,它沒有值的複製,通過引用它們的其他對象的引用來共用它們。

 

兩篇文章原文:http://www.cnblogs.com/huangting2009/archive/2009/03/13/1410634.html
還有:http://blog.csdn.net/ifooler/archive/2007/05/06/1598452.aspx

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.