Variables et question existentielle ...

[Résolu]
Signaler
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009
-
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009
-
Bonjour,
J'ai une petite question qui me turlupine ... J'ai cette classe :


    class Test
    {
        private int[] X;
        public Test(int[] x)
        {
            this.X = x;
        }
        public void ChangeValue()
        {
            for (int i = 0; i < this.X.Length; i++)
            {
                this.X[i] = i;
            }
        }
    }


Rien de bien compliqué, vous en conviendrez ... Seulement si je fais :


            int[] x = new int[] { 0, 0, 0 };
            Test test = new Test(x);
            test.ChangeValue();
           
// On a maintenant x == new int[]{0, 1, 2} ... La valeur de la variable a changé.


Mais le truc, c'est que si je fais une classe analogue avec au lieu de mettre un type int[], mais seulement un type int, bah la valeur de change pas ...
En fait, il doit y avoir des passages par références par défault ou non ... Mais lesquelles ? Je suis sur que ça relève de la connaissance de base du C# ... Mais je ne l'ai pas. Donc si quelqu'un peut m'expliquer. Et si quelqu'un peut m'expliquer comment faire pour que la valeur ne change pas ... Merci !
++ !
LocalStone

4 réponses

Messages postés
129
Date d'inscription
mardi 22 novembre 2005
Statut
Membre
Dernière intervention
30 décembre 2007
3
Pour faire passer un type valeur par référence, il suffit d'utiliser le mot-clé ref :
<hr />// Déclaration de la méthode
void MyMethod(ref int i);
// Appel : le paramètre est passé par référence
int val = 12;
MyMethod(ref val);
<hr />
Pour ce qui est de passer des types références par valeur, à ma connaissance ce n'est pas possible : les types références sont toujours passés par référence. Il faut donc explicitement copier la variable et passer en paramètre une référence vers la nouvelle copie.

Si l'objet n'implémente pas ICloneable, tu peux à la rigueur (en fonction du type de l'objet) créer une nouvelle instance et copier "manuellement" les champs, s'ils sont accessibles.
Messages postés
129
Date d'inscription
mardi 22 novembre 2005
Statut
Membre
Dernière intervention
30 décembre 2007
3
Salut,

Effectivement, les types tableaux sont toujours passés par référence, contrairement aux types valeurs (comme int) qui, comme leur nom l'indique, sont passés (par défaut) par valeur.

Tu peux utiliser la méthode Clone() de la classe Array pour retourner une copie de ton tableau et la passer en paramètre du constructeur :


<hr />
int[] x = new int[] {0,0,0};
Test test = new Test((int[])x.Clone());
test.ChangeValue();
<hr />Note le cast en (int[]), nécessaire car Clone() renvoie une valeur de type object.
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009

J'me disais aussi ... En fait, c'est pas ésotérique alors. Merci de ta réponse ! Mais j'ai une autre question ...

En fait, les types valeurs, ce sont tous les types de base (int, float,
etc.). Du coup, eux, ils sont passés par valeur. Par contre, tous les
autres objets (pas seulement les tableaux) sont passés par référence.
Mais alors ... Comment faire pour passer un objet (qui ne possède pas
l'interface IClonable) par valeur ? Et comment faire pour passer un
type valeur ... Par référence ?

Merci !

++ !
LocalStone
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009

Merci beaucoup pour tes précisions. Je crois que tu viens de me faire éviter une semaine entière de débuggage, là !
LocalStone