List - stocker des anciennes valeurs [Résolu]

Signaler
Messages postés
57
Date d'inscription
vendredi 24 mars 2006
Statut
Membre
Dernière intervention
2 août 2007
-
Messages postés
268
Date d'inscription
samedi 22 février 2003
Statut
Membre
Dernière intervention
24 avril 2013
-
Bonjour,

j'ai créé une classe point :

class pt
    {
        /*déclaration des attributs privés*/
        private float x;
        private float y;
     }

J'ai des accesseurs en écriture, en lecture et un constructeur qui prends en paramètres x et y.

Je crèe un liste de points :

list lis = new list();
pt p = new pt(2,0);
pt p1 = new pt(1,0);
lis.add(p);
lis.add(p1);

Je voudrais stocker ces anciennes valeurs car je vais modifier les coordonnées des points, je cree un nouvelle liste :

list lis_old = new list ();
//recopie de lis dans lis_old
lis_old = lis;

//modification des coordonnées dans ma lis
foreach pt p in lis
{
    p.set_x(p.get_x() + 10);
    p.set_y(p.get_y() - 5);
}

le problème avec ce code est que les valeurs de ma lis_old sont également modifié comment je peux faire svp pour garder ces anciennes valeurs.
Merci d'avance.

Laurent

10 réponses

Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
85
public pt Clone()
{
   return new pt(this.x, this.y);
}

Mais c'est vrai que si tu n'ajoutes rien fonctionnellement, tu peux peut être utiliser les structures Point existantes (qui du coup sont des types valeurs et éliminent ton "problème")

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
85
Salut,

Comme il s'agit d'une classe, ton type pt est un type référence, tu as donc en fait les références aux mêmes objets dans les 2 listes.
Lors de la copie il faut donc que tu crées de nouvelles instances avec les mêmes valeurs.
Pour faciliter la tâche tu peux par exemple créer une méthode Clone (implémentation de ICloneable ou méthode Clone fortement typée) et t'en servir durant la phase de copie.

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
268
Date d'inscription
samedi 22 février 2003
Statut
Membre
Dernière intervention
24 avril 2013
3
Ou bien tu utilise une structure au lieu d'une classe (structure est un type valeur)
il est a noter que dans System.Drawing il éxiste tout un tas de structure de ce type :

Point, PointF, Size, SizeF, Rectangle, RectangleF ....
donc c'est par forcement la peine de réinventer la roue...
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
Salut,

List< PointF > list = new List< PointF >( );
list.AddRange
(
    new PointF[ ]
    {
        new PointF( 0.1f, 0.1f ),
        new PointF( 0.2f, 0.2f )
    }
);


List< PointF > copy = new List< PointF >( list.ToArray( ) );
Messages postés
57
Date d'inscription
vendredi 24 mars 2006
Statut
Membre
Dernière intervention
2 août 2007

coq,

as tu une idée pour la méthode clone.

D'avance Merci
Messages postés
268
Date d'inscription
samedi 22 février 2003
Statut
Membre
Dernière intervention
24 avril 2013
3
ceci devrait fonctionner :
class pt, IClonable
{
   /*déclaration des attributs privés*/
   private float x;
   private float y;

   public float X
   {
      get{return this.x;}
      set{this.x=value;}
   }

   public float Y
   {
      get{return this.y;}
      set{this.y=value;}
   }

   public pt (float x,float y)
   {
      this.x=x;
      this.y=y;
   }

   public Object Clone ()
   {
      return new pt(this.x,this.y);
   }
}



ATTENTION : une classe prend plus de place en mémoire qu'une structure équivalente donc si tu utilise bcp de classe pt et que tu n'as pas besion de referencer le même ojet depuis plusieurs partie du code, essaie de changer ta classe en structure.
Messages postés
268
Date d'inscription
samedi 22 février 2003
Statut
Membre
Dernière intervention
24 avril 2013
3
Oups y'a comme une redondance!!! (j'ai été moins rapide ...)

mais la si t'a pas trouverton bonheur on pourrat pas faire mieux!
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
85
"class pt, IClonable" => class pt : ICloneable
;-)

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
Struct ou class de toute façon le problème est là :

list lis_old = new list ();
//recopie de lis dans lis_old
lis_old = lis;
Messages postés
268
Date d'inscription
samedi 22 février 2003
Statut
Membre
Dernière intervention
24 avril 2013
3
Putain des fois on est C...

Bien vue Lutinor (y'as des jours ou on devrait rester coucher)
merci pour la correction Coq


Explications pour 729290 pitch6969 :

//Là tu créer une list reférencer par lis
list lis = new list();
//Là tu créer une deuxième liste référencé par lis_old
list lis_old = new list ();
//ERREUR : recopie de lis dans lis_old
//En fait la tu "dis" : lis_Old référence maintenant la liste lis (donc en fait lis et lis_old sont le même objet;)
lis_old = lis;
// il faudrait donc "dire" d'ajouter dans Lis_Old les objects qui sont dans lis :

foreach(pt point in lis)
   lis_old.add((pt)(pt.clone()));

//avec pt en structure on pourait faire :
foreach(pt point in lis)
   lisold.add(pt);
//On a donc fais l'économie d'un appel de fonction a chaque boucle (Clone()).
et en fin de compte ou pourait même faire :

//Là tu créer une list reférencer par lis
list lis = new list();
//Là tu créer une deuxième liste référencé par lis_old et tul'inisialise avec les donnée de lis
list lis_old = new list (lis);
//mais uniquement si pt est une structure et pas une classe (t'as vue Une seulle ligne pour faire la copie avec un structure...)
//En fait si tu fais cette derniere méthode a avec pt en classe et pas en structure tu auras toujours le probléme de référence, mais plus au même endroi, lis et lis_old seront bien deux list différente, mais elle contiendront des référence vers les mêmes objet pt.