Krzysztof Radzimski

Pasja tworzenia

Deep clone copy - czyli jak zaimplementować klonowanie obiektów.

10 styczeń
Opublikował Krzysztof Radzimski 10. stycznia 2012 17:13

 

Tworzymy sobie interfejs który pomoże nam zwracać konkretny typ obiektu na nie zwykłe object.

namespace System {

/// <summary>
///  Supports cloning, which creates a new instance of a class with the same value
///     as an existing instance.
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ICloneable<T> : ICloneable {
/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
/// <returns>A new object that is a copy of this instance.</returns>
new T Clone();
}
}

Teraz implementujemy nasz interfejs w klasie, którą ma być klonowalna. Klasa taka powinna być oznaczona atrybutem [Serializable], ponieważ całe to klonowanie oparte jest na serializacji.

[Serializable]
public sealed class MyClass: ICloneable<MyClass> {
// ... jakieś właściwości, metody itd.

#region ICloneable Members
/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
/// <returns>
/// A new object that is a copy of this instance.
/// </returns>
object ICloneable.Clone() {
using (var ms = new System.IO.MemoryStream()) {
var bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(null,
 new System.Runtime.Serialization.StreamingContext(
 System.Runtime.Serialization.StreamingContextStates.Clone));
bf.Serialize(ms, this);
ms.Seek(0, System.IO.SeekOrigin.Begin);
return bf.Deserialize(ms);
}
}
#endregion
#region ICloneable<MyClass> Members
/// <summary>
/// Clones this instance.
/// </summary>
/// <returns></returns>
public MyClass Clone() {
return (this as ICloneable).Clone() as MyClass;
}
#endregion }

Trzeba pamiętać że wszystkie właściwości, które są obiektami złożonymi muszą się dać zserializować.

Teraz można wykorzystać naszą klasę:

var myClass = new MyClass();
// ... coś tam
var clone = myClass.Clone();

To wszystko, Oczywiście można by zrobić klonowanie z wykorzystaniem  this.MemberwiseClone() ale taka kopia jest płytka ... czyli typy referencyjne nie są klonowane 

 

Tagi: | Kategorie: Programowanie

Wyślij link na adres e-mail | Link do tego postu | RSSRSS comment feed