C#通過序列化實現深拷貝

來源:互聯網
上載者:User
關於淺拷貝和深拷貝,我的理解不是很清晰,簡單說來,我認為是這樣子:

  淺拷貝:引用成員在被拷貝時僅複製來源物件中引用成員的地址到新對象中,所以在新對象中對引用成員變更會影響到來源物件(除對引用成員進行賦值外)。

  深拷貝:引用成員在拷貝時建立一個引用對象到新對象中,且將來源物件中引用對象的成員值複製到新對象的引用對象中,所以在新對象中對引用成員變更不會影響來源物件。

  說起來概念也簡單,我想大家糾結的是如何?深拷貝?淺拷貝的實現很簡單,調用Object.MemberwiseClone就萬事大吉了。在網上找了一個通過序列化實現深拷貝的例子,自己改了改,歡迎大家品頭論足。

  這段程式的輸出為:

 

  objA1.RefClass.Field = 10
  objA2.RefClass.Field = 10
  objA1.RefClass.Field = 10
  objA2.RefClass.Field = 30
  objB1.RefClass.Field = 20
  objB2.RefClass.Field = 10  

 

  要注意的是,本例中實現深拷貝的ClassB類及其引用成員RefClass類必須添加Serializable特性。

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApplication1
{
//被引用類,必須添加Serializable特性,否則不能實現序列化
[Serializable]
class RefClass
{
private int field;
public int Field
{
get { return field; }
set { this.field = value; }
}
}

//淺拷貝樣本
class ClassA : ICloneable
{
private RefClass refClass;
public RefClass RefClass
{
get { return refClass; }
set { refClass = value; }
}

public ClassA()
{
refClass = new RefClass();
}

public object Clone()
{
//調用MemberwiseClone實現淺拷貝
return MemberwiseClone();
}
}

//深拷貝樣本,必須添加Serializable特性,否則不能實現序列化
[Serializable]
class ClassB : ICloneable
{
private RefClass refClass;
public RefClass RefClass
{
get { return refClass; }
}

public ClassB()
{
refClass = new RefClass();
}

//深拷貝
public object Clone()
{
//建立記憶體流
MemoryStream ms = new MemoryStream();
//以二進位格式進行序列化
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, this);
//還原序列化當前執行個體到一個object
ms.Seek(0, 0);
object obj = bf.Deserialize(ms);
//關閉記憶體流
ms.Close();
return obj;
}
}

class Program
{
static void Main(string[] args)
{
//淺拷貝
ClassA objA1 = new ClassA();
objA1.RefClass.Field = 20;
ClassA objA2 = (ClassA)objA1.Clone();
//在新對象中修改RefClass的Field值,來源物件中的值亦更改
objA2.RefClass.Field = 10;
Console.WriteLine("objA1.RefClass.Field = " + objA1.RefClass.Field.ToString());
Console.WriteLine("objA2.RefClass.Field = " + objA2.RefClass.Field.ToString());
//對新對象中的RefClass重新進行賦值操作,不影響來源物件
objA2.RefClass = new RefClass();
objA2.RefClass.Field = 30;
Console.WriteLine("objA1.RefClass.Field = " + objA1.RefClass.Field.ToString());
Console.WriteLine("objA2.RefClass.Field = " + objA2.RefClass.Field.ToString());
//深拷貝
ClassB objB1 = new ClassB();
objB1.RefClass.Field = 20;
ClassB objB2 = (ClassB)objB1.Clone();
//在新對象中修改RefClass的Field值,來源物件中的值不變
objB2.RefClass.Field = 10;
Console.WriteLine("objB1.RefClass.Field = " + objB1.RefClass.Field.ToString());
Console.WriteLine("objB2.RefClass.Field = " + objB2.RefClass.Field.ToString());
Console.ReadKey();
}
}
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.