.NET物件克隆的深究 (轉)
By ?id=144339">Manoj G :namespace prefix = o ns = "urn:schemas--com::office" />
Posted 1 Aug
Applied to:
, XP, W2K, 1.1,
摘要:本文討論了為什麼需要的克隆,怎樣克隆以及對克隆的一些思考。
files - 10 Kb
簡介
本文我將討論.NET中一個比較感興趣的方面——物件克隆。下面將討論物件克隆的必要性、物件克隆的方法以及關於物件克隆的一些思考。
背景
大家一定知道.NET物件是有二大型別的: 值型別和引用型別。 值型別物件的變數表示物件本身,而且具有“copy-on-assignment”的行為。也就是說, 以下的討論不適用於值型別。
另一方面,引用型別的變數實際上是指向堆上的。 因此,如果你建立了一個引用型別的變數,並且將一個已存在的物件分配給它,實際上是建立了指向堆上的相同記憶體的另外一個物件。本文就是討論這樣的情況:建立的一個物件的新的複製,並且儲存在一個變數中!
為什麼要克隆?
我認為當設定一個物件的狀態要付出昂貴的代價,並且又需要取得該物件的一個複製以便改變當前的一些狀態時,克隆就顯得十分必要。下面列舉一個剛好能體現我剛剛所說的情況的例子。 就拿 DataTable 類來說吧。建立一個 DataTable 會包含諸如以下的操作:為取得架構和資料而查詢、新增、設定主鍵等等。那麼,當需要該 DataTable 的一個新的複製,哪怕是對架構作極小的改變或新增新的一行記錄等等, 明智的選擇會是克隆已存在的物件再對其進行操作,而不是建立一個新的DataTable, 那樣將需要更多的時間和資源。
克隆也廣泛應用於陣列和集合,這些時候往往會多次需要已存在物件的一個複製。
克隆的型別
我們基於克隆的程度將克隆分成兩大類:“深層”克隆和“淺表”克隆。“淺表”克隆得到一個新的例項,一個與原始物件型別相同、包含值型別欄位的複製。但是,如果欄位是引用型別的, 該引用將被複製, 而不是複製引用的物件。 因此,原始物件的引用和克隆物件的引用都指向同一個物件。另一方面, 物件的“深層”克隆包含原始物件直接或間接引用的物件的所有複製。下面舉例說明。
模式的比較 hspace=0 src="/Develop/ArticleImages/20/20324/CSDN_Dev_Image_2003-8-81651000.jpg" align=baseline border=0>
物件X引用物件A,物件A引用物件M。物件X的“淺表”克隆物件Y,同樣也引用了物件A。相對比的是,物件X的“深層”克隆物件Y,卻直接引用了物件B,並且間接引用物件N,這裡,物件B是物件A的複製,物件N是物件M的複製。
實現克隆
System.提供了受保護的方法 MemberwiseClone,可用來實現“淺表”克隆。由於該方法標記為“受保護”級別,因此,我們只能在繼承類或該類內部才能訪問該方法。
.NET定義了一個IClonable介面,一個需要“深層”克隆而不是“淺表”克隆的類必須實現該介面。我們需要提供一個好的實現方法來達到該介面的Clone方法實現的功能。
有許多方法可以實現“深層”克隆。一個方法是將物件化到記憶體流中,然後反序列化到一個新的物件。我們將使用一個二進位制(Binary)的 Formatter類或P formatter類來進行深層序列化。做一個深寫成連載長篇而刊登的 formatter 。 這個方法的問題是類和它的成員 (完整的類表) 必須被標記為serializable,否則formatter會發生錯誤。
反射是另外一個能達到相同目的的方法。 Amir Harel寫的一篇好文章吸引了我, 他使用該方法提供一個好的克隆實現。 這篇文章討論得非常好! 以下是連結:
/cloneimpl_class.asp">
上面討論的任何一個方法,都要求物件的成員型別能支援自我克隆,以確保“深層”克隆能成功進行。也就是說, 物件必須是可序列化的(serializable) ,或者每個獨立的成員必須提供IClonable的實現。 如果不這樣,我們根本不可能對物件進行“深層”克隆!
綜述
克隆是提供給員的一個很好的方法。但是, 我們應該知道什麼時候需要提供這樣的功能,而且在某些情況下,嚴格地說,物件不應該提供這一個特性。 以Transaction 類為例, 就不支援克隆。這一個類代表了資料庫的一個事務。 克隆該物件沒有任何意義,因為我們可能不能夠理解一個資料庫的一個活動的事務的克隆! 因此,如果你認為克隆物件的狀態會產生應用程式邏輯上的矛盾,就不需要支援克隆。
(完)
參看原文:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-981977/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- js物件的深度克隆!JS物件
- Java中的物件“克隆”Java物件
- 原生js實現物件的深克隆以及淺克隆JS物件
- js深度克隆物件JS物件
- 物件如何深度克隆物件
- 詳解 Java 中的物件克隆Java物件
- js克隆一個物件JS物件
- JS型別判斷、物件克隆、陣列克隆JS型別物件陣列
- Java 的常見 API 與物件克隆)JavaAPI物件
- vue 克隆物件時遇到的問題Vue物件
- .NET 透過原始碼深究依賴注入原理原始碼依賴注入
- 在 JavaScript 中如何克隆物件?JavaScript物件
- js之物件深淺克隆JS物件
- JS物件深度克隆/複製JS物件
- Java值物件或DTO克隆工具Java物件
- PDB克隆遷移轉換
- 在.net中使用AutoMapper進行物件對映,物件相互轉,簡單方便APP物件
- 深究免費代理ip的弊端
- JS 物件合併與克隆方法的分類與比較JS物件
- 什麼要使用克隆、如何實現克隆物件、序列化與反序列實現克隆的好處、深拷貝與淺拷貝物件
- .NET Core 物件池的使用物件
- 淺克隆和深克隆的用法
- 使用c#強大的表示式樹實現物件的深克隆C#物件
- 深究Function.prototype.bindFunction
- JS json字串轉物件、物件轉字串JSON字串物件
- .net core Configuration物件物件
- JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆物件的區別JavaScriptStructJSON物件
- Vue.js - 陣列和物件的賦值動態變化 & 克隆Vue.js陣列物件賦值
- jquery物件和DOM物件的互相轉換jQuery物件
- vue陣列的深克隆和淺克隆Vue陣列
- 深入理解Java的淺克隆與深克隆Java
- 【JQuery】DOM物件和JQuery物件的互相轉換jQuery物件
- 【譯】.NET 物件分配工具物件
- 三目運算、物件克隆、深拷貝和淺拷貝物件
- 物件轉型物件
- 深究mv移動資料夾時`/`的用法
- 深究cp拷貝資料夾時`/`的用法
- 小程式倒數計時深究
- xlua中lua物件到c#物件的轉型物件C#