Copie profonde d'objets en C#
Bonjour.
Je cherchais une méthode permettant de faire une copie profonde (DeepClone) d'objets en C#.
Sur :
http://www.code-magazine.com/Article...uickid=0601121
J'ai trouvé la méthode suivant qui me parait vraiment chouette :
// C#
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public static object DeepClone(
object obj)
{
// Create a "deep" clone of
// an object. That is, copy not only
// the object and its pointers
// to other objects, but create
// copies of all the subsidiary
// objects as well. This code even
// handles recursive relationships.
object objResult = null;
using (MemoryStream ms =
new MemoryStream())
{
BinaryFormatter bf =
new BinaryFormatter();
bf.Serialize(ms, obj);
// Rewind back to the beginning
// of the memory stream.
// Deserialize the data, then
// close the memory stream.
ms.Position = 0;
objResult = bf.Deserialize(ms);
}
return objResult;
} |
Quelqu'un l'a t-il expérimenté ?
J'aimerai avoir vos critiques sur cette méthode qui me parait parfaite.
Il y a t-il des cas ou cela risque de ne pas marcher ?
Merci pour vos réponses.
Copie profonde (code en Français)
Voici le même code mais cette fois-ci en français et avec des commentaires.
Je trouve vraiment cette méthode géniale ! (je peux me permettre cette remarque, car cette méthode n'est pas de moi, je me suis simplement contenté de la traduire en Français -> un lien vers le site de l'auteur figure en commentaire).
Elle mériterait peut-être de figurer dans la faq C#.
Qu'en pensez-vous ?
/// <summary>
/// Méthode permettant de faire une copie profonde d'un objet
/// </summary>
/// <remarks>
/// Cette méthode (géniale !) provient du site : http://www.code-magazine.com/Article...uickid=0601121
/// Son auteur est Ken Getz
/// Elle nécessite toutefois que tous les éléments de l'objet à cloner
/// soit sérialisable
/// Rappel : pour rendre sérialisable une classe il est nécessaire d'ajouter
/// le mot clé [Serializable] devant sa déclaration)
/// On peut, via cette méthode, cloner donc tout type d'objet du moment que
/// celui-ci est sérialisable, en faisant un simple cast.
/// Exemple :
/// MaClassePerso oSource = new MaClassePerso();
/// MaClassePerso oCopieProfonde;
/// oCopieProfonde = (MaClassePerso)DeepClone(oSource);
///
/// Dans cet exemple oCopieProfonde est maintenant une copie profonde de oSource !
/// </remarks>
/// <param name="oPar_ObjetAClonerProfondemment">
/// Objet à cloner profondément
/// </param>
/// <returns>
/// Objet contenant une copie profonde de l'objet passé en paramètre
/// </returns>
public static object DeepClone(object oPar_ObjetAClonerProfondemment)
{
object oLocal_ValeurRetour = null; //§/Objet retournée par cette méthode
//§/Si l'objet a clonr passé en paramètre n'est pas null
//§/En effet, s'il n'est pas instancié inutile de faire
//§/le traitement qui suit
//§/cette méthode va simplement également retourner une
//§/nouvelle référence (celle de la valeur retour instanciée localement)
//§/contenant null
if (oPar_ObjetAClonerProfondemment != null)
{
//§/Ici on fait un using de façon à optimiser la gestion de la mémoire
//§/Cet objet MemoryStream sera en effet immédiatement supprimé
//§/après son utilisation par le Garbage Collector
//§/Cette optimisation peut effectivement avoir son importance
//§/si cette méthode doit être appellée dans un lourd traitement en boucle
using (MemoryStream msLocal_MemoryStream =
new MemoryStream())
{
//§/On créé un BinaryFormatter qui va être utiliser pour la sérialisation de l'objet
BinaryFormatter oLocal_BinaryFormatter = new BinaryFormatter();
//§/Puis on sérialise l'objet passé en paramètre
oLocal_BinaryFormatter.Serialize(msLocal_MemoryStream, oPar_ObjetAClonerProfondemment);
//§/Ensuite on désérialize ce objet dans
// Rewind back to the beginning
// of the memory stream.
// Deserialize the data, then
// close the memory stream.
//§/On se repositionne en début du MemoryStream
msLocal_MemoryStream.Position = 0;
//§/Puis on désérialise l'objet dans la valeur retour
//§/Ce qui a pour effet de récupérer une copie profonde de celui-ci
oLocal_ValeurRetour = oLocal_BinaryFormatter.Deserialize(msLocal_MemoryStream);
}
}
//§/Retourner l'objet correspondant à la copie profonde
return oLocal_ValeurRetour;
}