IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Copie profonde d'objets en C#


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 92
    Par défaut 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  2. #2
    Rédacteur

    Avatar de Jérôme Lambert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2003
    Messages
    4 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 451
    Par défaut
    Cette technique ne pourra copier un object uniquement si celui est marqué Serializable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [System.Serializable]
    public class YourClass : System.ICloneable
    {
    }

    Ce qui n'est pas le cas dans l'exemple ou alors c'est précisé dans l'article, ce que je n'ai pas vu.

    Mais en plus, les objets contenus dans l'objet principal doivent aussi avoir l'attribut Serializable, sinon, ça ne fonctionnera pas.

    Donc oui, ça peut copier un objet (en respectant les conditions) mais ça ne pourra pas copier n'importe quel objet !

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 92
    Par défaut Serializable
    Il y a t-il une méthode meilleure ?

  4. #4
    Rédacteur

    Avatar de Jérôme Lambert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2003
    Messages
    4 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 451
    Par défaut
    Citation Envoyé par sandre Voir le message
    Il y a t-il une méthode meilleure ?
    Je n'en connais pas... Pas sûr que ça existe.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 92
    Par défaut [Serializable]
    De toute façon rajouter le [Serializable] devant chaque classe développée n'est pas, en soi, une grosse contrainte.

    Il y a t-il des classes du Framework qui ne soient pas nativement sérializable ?

    En tout cas je trouve cette classe très pratique.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 92
    Par défaut 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;
    }

  7. #7
    Rédacteur

    Avatar de Jérôme Lambert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2003
    Messages
    4 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 451
    Par défaut
    Citation Envoyé par sandre Voir le message
    De toute façon rajouter le [Serializable] devant chaque classe développée n'est pas, en soi, une grosse contrainte.

    Il y a t-il des classes du Framework qui ne soient pas nativement sérializable ?

    En tout cas je trouve cette classe très pratique.
    C'est bien ce que je voulais dire, à partir du moment où tu joues avec tes propres classes et celles du framework qui sont Serializable, il n'y a pas de soucis.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. vb 6 : copie profonde d'un objet
    Par TaymouWan dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 10/08/2009, 11h04
  2. copie d' un objet
    Par Nayila dans le forum Langage
    Réponses: 3
    Dernier message: 25/10/2007, 20h30
  3. [Tableaux] Copie d'un objet référencé dans un tableau
    Par Nullos Oracle dans le forum Langage
    Réponses: 5
    Dernier message: 12/07/2007, 21h42
  4. [VB.NET]Comment s'opère la copie profonde d'objet?
    Par NicolasJolet dans le forum VB.NET
    Réponses: 5
    Dernier message: 29/03/2006, 15h23
  5. Réponses: 7
    Dernier message: 13/02/2006, 18h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo