簡介:
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看到我們用二進位制序列化和反序列化實現了iclone介面的clone方法。這個clone方法我們可以提出來作為乙個擴充套件方法:[serializable]
2public
class
employee : icloneable35
public
string employeename
6public department department 78
public
object
clone()919
return
null;20
}21}22 }
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 到另乙個容器控制項內,而保留原來的控制項。為了更好地把問題說清楚,請看...