"Deep Copy" e "Shallow Copy"
pubblicato il 28/08/2008
Quando vogliamo ottenere la copia di un oggetto, abbiamo a disposizione due modalità:
- Shallow Copy
- Deep Copy
Shallow Copy
La copia Shallow (lett. superficiale), consente di ottenere una copia dell'oggetto di partenza con la copia delle proprietà di tipo Value; tuttavia le proprietà di tipo Reference puntano ancora agli stessi oggetti puntati dalle corrispondenti proprietà dell'oggetto sorgente della copia.
Deep Copy
La copia Deep (lett. profonda) invece consente di ottenere una copia nel senso più pieno del termine, quindi anche per le proprietà di tipo Reference verranno creati dei nuovi oggetti che conterranno gli stessi "valori" degli oggetti di partenza, ma saranno separati da questi.
Uno dei metodi più immediati per ottenere una Deep Copy consiste nel serializzare l'oggetto in memoria e poi de-serializzarlo nuovamente nel nuovo ogggetto "clone". Prerequisito fondamentale, ovviamente, è che l'oggetto da copiare sia serializzabile.
Namespace tmSoft.ObjectUtils
Public
Shared Function DeepClone(source As Object) As
Object
Dim binaryFormatter As
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim
memStream As System.IO.MemoryStream = New
System.IO.MemoryStream()
binaryFormatter = New
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(Nothing, New
System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Clone))
binaryFormatter.Serialize(memStream,
source)
memStream.Seek(0,
System.IO.SeekOrigin.Begin)
return
binaryFormatter.Deserialize(memStream) End Function
End
Namespace
N.B.: Nello snippet qui presentato ho aggiunto tutte le namespace per
mostrare da dove arrivano tutte le classi in gioco; nel codice reale avrei
aggiunto delle belle Import... snellendo così il codice
A questo punto non resta che richiamare il metodo dalla classe che si vuole clonare; una buona pratica può essere quella di realizzare un'interfaccia (ICloneable, per esempio):
Public Interface ICloneable
Public
Function DeepClone(source as Object) As Object
End Interface
E quindi implementare l'interfaccia nella classe da clonare:
Public Class MyDeeplyCloneable
Implements
ICloneable
Public Function DeepClone(source as Object) As
Object
Return
tmSoft.ObjectUtils.DeepClone(Me)
End Function
End
Class
