Commentçamarche.net
CodeS-SourceS
Rechercher un code, un tuto, une réponse
Posez votre question »

Passage par référence et par valeur

Juillet 2015


Passage de variables par référence et par valeur en C#

Préambule


Petit tutoriel assez simple qui montre la différence entre le passage de paramètre par valeur et par référence via des exemples graphiques.


Introduction


Pour savoir si ce tutoriel peut vous apprendre quelque chose de nouveau, répondez aux questions suivantes :


Soit le programme suivant :

namespace MyApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Variable test
            Test t;
            t = new Test();
            t.str = "Init";
            //Variable int
            int i = 5;
            
            Program pg = new Program();
            prg.Test1(i);
            prg.Test2(t);
            prg.Test3(ref i);
            prg.Test4(ref t);
        }
        
        public void Test1(int x)
        {
            x = 10;
        }
        
        public void Test2(Test t1)
        {
            t1 = new Test();
        }
        
        public void Test3(ref int x1)
        {
            x1 = 15;
        }
        
        public void Test4(ref Test t2)
        {
            t2 = new Test();
        }
    }
    
    public class Test
    {
        public string str;
    }
}


En C#, par défaut, est-ce qu'une variable est passée en paramètre d'une fonction par valeur ou par référence ? Exemple : Lors de l'appel de la méthode Test2 ci-dessus, t1 est-il passé par valeur ou par référence ?
Réponse: Par défaut, le passage se fait par valeur. Dans l'exemple de la méthode Test2, t1 est une référence sur t qui est passée par valeur.

Que vaut la variable i après exécution de la méthode Test1 ?
Réponse : i vaut 5

Que vaut la variable t après exécution de la méthode Test2 ?
Réponse : t n'a pas changé, sa variable str vaut toujours init

Que vaut la variable i après exécution de la méthode Test3 ?
Réponse : i vaut 15

Que vaut la variable t après exécution de la méthode Test4 ?
Réponse : t est réinstancié, str est null

Si Test était une structure et pas une classes, aurait-on les mêmes résultats ?
Réponse : Dans ce cas précis, oui.

Si vous n'avez pas tout fait juste, ce tutoriel pourra peut-être vous être utile ! :)

Explications


Des schémas valent sûrement bien mieux qu'un long discours. Voyons dans chacun des cas ce qui se passe sur le Stack et sur le Heap pour comprendre le fonctionnement du programme.

Dans les exemples qui suivent, le Stack sera toujours dessiné en rouge, alors que le Heap sera lui en bleu.

Premier exemple, exécution de Test1


On commence par mettre i sur le Stack car c'est une valeur
int i = 5 ;


On appelle maintenant la méthode Test1. x est crée sur le Stack, car c'est une valeur passée par valeur. Elle prend la valeur 5 car c'est la valeur qu'on lui passe en paramètre.
Ensuite, on lui affecte la valeur 4.

La méthode retourne, x meurent (GC) car elle était locale à Test1. Après le retour de la méthode, i reste donc inchangé.

Deuxième exemple, exécution de Test2


On commence par mettre une référence de t sur le Stack. Cette référence pointe sur l'objet qui est lui sur le Heap.
Test t = new Test() ;


On appelle maintenant la méthode Test2. t1 est une référence passée par valeur, elle est donc mise sur le Stack et pointe au même endroit sur le Heap que t.

On demande ensuite de créer une nouvelle référence de l'objet t1.
t1 = new Test() ;


La méthode retourne, t1 meurent (GC) car elle était locale à Test2. Après le retour de la méthode, t reste donc inchangé.

Troisième exemple, exécution de Test3


On commence par mettre i sur le Stack car c'est une valeur
int i = 5 ;


On appelle maintenant la méthode Test3. x est crée sur le Stack, c'est une référence qui pointe sur i car c'est une valeur passée par référence. x pointe donc sur la valeur 5.
On affecte ensuite à x la valeur 15. Puisque x pointe sur i, i = 15.

La méthode retourne, x meurent (GC) car elle était locale à Test3. Après le retour de la méthode, i vaut donc maintenant 15.

Quatrième et dernier exemple, exécution de Test4


On commence par mettre une référence de t sur le Stack. Cette référence pointe sur l'objet qui est lui sur le Heap.
Test t = new Test() ;


On appelle maintenant la méthode Test4. t2 est une référence passée par référence, elle est donc mise sur le Stack et pointe sur t

On demande ensuite de créer une nouvelle référence de l'objet t2.
t2 = new Test() ;


Puisqu'il pointe sur t, on obtient le schéma suivant :

La méthode retourne, t2 meurent (GC) car elle était locale à Test4. Après le retour de la méthode, t a donc été réinitialisé et sa variable str est null.

Conclusion


Voilà, j'espère que ces quelques schémas ont pu éclairer certaines lanternes ^^
Pour une lecture illimitée hors ligne, vous avez la possibilité de télécharger gratuitement cet article au format PDF :
Passage-par-reference-et-par-valeur.pdf

A voir également

Dans la même catégorie

Publié par cs_Bidou. - Dernière mise à jour par BunoCS
Ce document intitulé «  Passage par référence et par valeur  » issu de CodeS-SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Ajouter un commentaire

Commentaires

Ajouter un commentaire
Extension du Ribbon/Ruban de Word 2007 avec VSTO 2005 SE
XNA Framework 1.0 Refresh : du texte dans vos jeux