object.memberwiseclone 方法
建立當前 object 的淺表副本。
protected object memberwiseclone()
memberwiseclone 方法建立乙個淺表副本,方法是建立乙個新物件,然後將當前物件的非靜態字段複製到該新物件。 如果欄位是值型別的,則對該字段執行逐位複製。 如果欄位是引用型別,則複製引用但不複製引用的物件;因此,原始物件及其複本引用同一物件。
例如,考慮物件x引用物件 a 和 b , 物件 b 依次引用物件 c。 x 的淺表副本建立乙個新物件 x2,該物件也引用物件 a 和 b。 相比而言,x 的深層副本建立乙個新物件 x2,該物件引用新物件 a2 和 b2(分別為 a 和 b 的副本)。 b2 又引用新物件 c2,c2 是 c 的副本。 該示例闡釋了淺層和深層複製操作之間的區別。
有很多方法可以實現深層複製操作,前提是淺表複製操作由 memberwiseclone 方法執行但不符合您的需求。
這些要求包括:
呼叫要複製的物件的類建構函式以建立含有從第乙個物件中提出的屬性值的第二個物件。 這假定物件的值完全由類建構函式定義。
呼叫 memberwiseclone 方法建立的物件的淺表副本,然後將指定新的物件,其值均相同,原始物件的任何屬性或字段的值是引用型別。 該示例中的 deepcopy 方法闡釋了這種方法。
序列化要深層複製的物件,然後將序列化的資料還原到另乙個物件變數。
使用帶遞迴的反射執行的深層複製操作。
下面的示例演示 memberwiseclone 方法。 它定義了 shallowcopy 方法,該方法通過呼叫 memberwiseclone 方法來在 person 物件上執行淺表複製操作。 它還定義了在 pers程式設計客棧on 物件上執行深層複製操作的deepcopy 方法。
using system;
public class idinfo}
public class person
public person deepcopy() }
public class example
public static void displayvalues(person p)
, age: ", p.name, p.age);
console.writeline(" value: ", p.idinfo.idnumber);
}}// the example displays the following output:
// original values of p1 and p2:
// p1 instance values:
// name: sam, age: 42
// value: 6565
// p2 instance values:
// name: sam, age: 42
// value: 6565
//
// values of p1 and p2 after changes to p1:
// p1 instance values:
// name: frank, age: 32
// value: 7878
// p2 instance values:
// name: sam, age: 42
// value: 7878
//
// values of p1 and p3 after changes to p1:
// p1 instance values:
// name: george, age: 39
// value: 8641
// p3 instance values:
// name: frank, age: 32
// value: 787程式設計客棧8
為了實現深度複製,我們就必須遍歷有相互引用的物件構成的圖,並需要處理其中的迴圈引用結構。這無疑是十分複雜的。幸好借助.net的序列化和反序列化機制,可以十分簡單的深度clone乙個物件。
原理很簡單,首先將物件序列化到記憶體流中,此時物件和物件引用的所用物件的狀態都被儲存到記憶體中。.net的序列化機制會自動處理迴圈引用的情況。然後將記憶體流中的狀態資訊反序列化到乙個新的物件中。
這樣乙個物件的深度複製就完成了。在原型設計模式中clone技術非常關鍵。
using system;
using system.io;
using system.runtime.serialization.formatters.binary;
namespace clonedemo;
public democlass clone1() //淺clone
public democlass clone2() //深clone
} class program
; democlass b = a.clone1();
democlass c = a.clone2();
// 更改 a 物件的iarr[0], 導致 b 物件的iarr[0] 也發生了變化 而 c不會變化
a.iarr[0] = 88;
console.writeline("memberwiseclone");
console.writeline(b.i);
foreach (var item in b.iarr)
console.writeline("clone2");
console.writeline(c.i);
foreach (var item in c.iarr)
console.readline();}}}
本文標題: 簡單談談c#中深拷貝、淺拷貝
本文位址:
談談深拷貝和淺拷貝
今天在做專案購物車需求的時候,遇到乙個同深拷貝 淺拷貝相關的問題,所以來談談深拷貝和淺拷貝。什麼是深拷貝?複製基本型別的屬性 引用型別的屬性複製,複製棧中的變數 和 變數指向堆記憶體中的物件的指標和堆記憶體中的物件。什麼是淺拷貝?複製基本型別的屬性 引用型別的屬性複製,複製棧中的變數 和 變數指向堆...
談談拷貝中坑 深拷貝與淺拷貝
1.堆 stack 和棧 heap stack為自動分配的記憶體空間,它由系統自動釋放 而heap則是動態分配的記憶體,大小不定也不會自動釋放。2.值與引用 js中有基本資料型別和引用型別 基本資料型別的變數和值都是存放在棧中,宣告之後會分配一塊記憶體區域,基本資料型別之間的賦值是直接把棧記憶體中存...
C 深拷貝 淺拷貝
c 深拷貝 淺拷貝 深拷貝 淺拷貝和直接指向引用的區別 深拷貝 淺拷貝都是重新開闢了記憶體空間,並且在新的記憶體空間裡面賦了物件本身 的值。直接指向引用是乙個物件直接指向另外乙個物件的引用,這兩個物件指向的是同一 塊記憶體空間,操作任乙個物件都會影響另外的物件。深拷貝和淺拷貝的區別 如果物件的成員都...