物件的深拷貝 序列化拷貝

2021-09-08 11:40:02 字數 3357 閱讀 5867

簡介:

system.object 幾乎是所有的類、結構、委託型別的基類。system.object有乙個memberwiseclone 的方法來幫助我們建立乙個當前物件的例項。

存在的問題:

system.object 提供的memberwiseclone 方法只是物件的淺拷貝,只能把當前物件的非靜態字段拷貝到新物件。如果屬性是值型別,那麼就把值拷貝乙份,如果是引用型別,那麼只拷貝對原物件的引用。這就意味著memberwiseclone 不能夠建立物件的深拷貝。

解決方案:

有很多實現深拷貝的方式,在這裡我只介紹其中的2種。

1.通過序列化和反序列化實現深拷貝。

2.通過反射來實現深拷貝。

今天我就先介紹第一種:序列化和反序列化實現深拷貝。

icloneable 介面提供給我們乙個可以自定義實現拷貝的clone方法。

序列化就是把物件轉換成位元組流的過程,反序列化相反,就是把位元組流轉換成原物件的過程。在.net中有很多序列化的方式,比如二進位制序列化、xml序列化等等。二進位制序列化要比xml序列化快得多。所以二進位制序列化是比較好的序列化和反序列化。

通過序列化和反序列化,能夠實現對乙個物件的深拷貝,但是前提是需要序列化和反序列化的類都要標記為serializable特性。

下面的例子,我建立乙個職員類,擁有乙個部門屬性。

1

[serializable]

2public

class

department35

public

string departmentname

6 }

1

[serializable]

2public

class

employee : icloneable35

public

string employeename

6public department department 78

public

object

clone()919

return

null;20

}21}22 }

看到我們用二進位制序列化和反序列化實現了iclone介面的clone方法。這個clone方法我們可以提出來作為乙個擴充套件方法:

1

public

static

class

objectextension212

}13 }

看源**:

1

using

system;

2using

system.collections.generic;

3using

system.linq;

4using

system.text;

5using

system.io;

6using

system.runtime.serialization.formatters.binary;78

namespace

serializecopy914

15public

string departmentname 16}

1718

[serializable]

19public

class

employee : icloneable

2022

public

string employeename

23public department department

2425

public

object clone()

263031}

32public

static

class

objectextension

334748}

4950}51

52 }

呼叫**:

1

using

system;

2using

system.collections.generic;

3using

system.linq;

4using

system.text;56

namespace

serializecopy7;

1718 employee empclone = emp.clone() as

employee;

1920 emp.employeeid = 1003

;21 emp.employeename = "

ttt"

;22 emp.department.departmentid = 3

;23 emp.department.departmentname = "

admin";

24 console.writeline("

----emp原始物件------");

25 console.writeline("

拷貝前departmentname應該是admin:

" +emp.department.departmentname);

26 console.writeline("

拷貝前departmentid應該是3:

" +emp.department.departmentid);

2728 console.writeline("

----empclone拷貝物件------");

29 console.writeline("

拷貝departmentname應該是examination:

" +empclone.department.departmentname);

30 console.writeline("

拷貝departmentid應該是1:

" +empclone.department.departmentid);

31console.readkey();32}

33}34 }

呼叫結果:

需要注意的一點是,用序列化和反序列化深拷貝,需要將需要拷貝的屬性標記為serializable

WPF控制項深拷貝 序列化 反序列化

今天debuglzq在做wpf拖動總結的時候,遇到了這個問題。baidu了下,貌似沒有解決這個問題的權威答案,遂寫下這篇博文。我想做的事情是 拖動乙個窗體內的控制項 rectangle 到另乙個容器控制項內,而保留原來的控制項。為了更好地把問題說清楚,請看如下 片段 void canvas1 dro...

WPF控制項深拷貝 序列化 反序列化

原文 wpf控制項深拷貝 序列化 反序列化 今天debuglzq在做wpf拖動總結的時候,遇到了這個問題。baidu了下,貌似沒有解決這個問題的權威答案,遂寫下這篇博文。我想做的事情是 拖動乙個窗體內的控制項 rectangle 到另乙個容器控制項內,而保留原來的控制項。為了更好地把問題說清楚,請看...

WPF控制項深拷貝 序列化 反序列化

原文 wpf控制項深拷貝 序列化 反序列化 今天debuglzq在做wpf拖動總結的時候,遇到了這個問題。baidu了下,貌似沒有解決這個問題的權威答案,遂寫下這篇博文。我想做的事情是 拖動乙個窗體內的控制項 rectangle 到另乙個容器控制項內,而保留原來的控制項。為了更好地把問題說清楚,請看...