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 :

Passage d'argument par valeur / référence


Sujet :

C#

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 11
    Points : 7
    Points
    7
    Par défaut Passage d'argument par valeur / référence
    Bonjour est-il possible d'avoir une explication simplifiée de ce concept de valeur et de référence car je n'arrive pas à totalement le saisir.
    D'avance merci.

  2. #2
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Je viens de trouver une bonne explication sur un autre site :
    .NET distingue deux types de données différentes :
    - les types valeurs (int, float, doube, struct, etc.) stockés sur la pile et passés en paramètres par copie
    - les types références (object, string, class, etc.) stockés sur le tas managé et passés obligatoirement en paramètre, par référence

    Pour forcer un type valeur à être passer en référence et pouvoir donc le modifier depuis une autre méthode, vous pouvez utiliser les mots clés ref ou out.

    out et ref fonctionnent de la même manière, excepté que out permet de passer par référence un paramètre non initialisé
    J’ai des questions à toutes vos réponses!

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 002
    Points : 552
    Points
    552
    Par défaut
    Vu le nombre d'articles techniques sur Internet sur ce sujet, je vais essayer une nouvelle méthode pédagogique pour expliquer le passage par référence et par valeur :

    Si je te dis que je gagne 2 500 euros. Tu peux me retourner "ouai il gagne pas trop mal sa vie". Ça, c'est du passage par valeur !

    Si maintenant je te donne en billets tout mon salaire de 2 500 euros. Que tu claques la moitié, et que tu me rendes 1 250 euros. Bon j'ai perdu un peu de tunes, il y a eu un peu d'effet de bord et de casse, car c’est du passage par référence !


    Heureusement que par défaut, on passe les entiers en valeur, car à force je perdrai pas mal d'argent avec toi !

    Le String de ta copine est un bel Objet, il n'est pas primitif mais se comporte comme tel; en effet le sacré vicelard qui a écrit la Framework, l'a rendu immuable (=pas modifiable), pour que le passage du String se fasse par copie! Du coup ta copine est sûr de ne jamais le perdre, ni même qu'il ne rétrécisse en le passant à la machine !

    EDIT:
    Merci tomlev pour la correction

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    merci les amis pour vos réponses et spécialement alavoler pour le type de réponse que je recherchais précisément!

  5. #5
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Citation Envoyé par alavoler Voir le message
    Si maintenant je te donne en billets tout mon salaire de 2 500 euros. Que tu claques la moitié, et que tu me rendes 1 250 euros. Bon j'ai perdu un peu de tunes, il y a eu un peu d'effet de bord et de casse, car c’est du passage par référence !
    Donc tu perds quoi en passant un paramètre par référence? du temps? des infos? de la ressource?
    J’ai des questions à toutes vos réponses!

  6. #6
    Membre émérite
    Avatar de azstar
    Homme Profil pro
    Architecte Technique BizTalk/.NET
    Inscrit en
    Juillet 2008
    Messages
    1 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Technique BizTalk/.NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 198
    Points : 2 424
    Points
    2 424
    Par défaut
    même si je n'ai pas totalement saisir l'exemple
    mais je pense que le simple est:

    le passage par valeur : on passe la valeur, pas l'objet lui même, ce qui fait s' il y'a un changement dans la valeur. l'objet gardera ça valeur initiale.
    le passage par référence :on passe l'objet lui même et ,si bien sûr, il a changé ça valeur changera.

    un exemple ça sera plus parlant


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      void Updatebyval(string valeur)
      {
            valeur="azstar;Version par valeur";
       }
      void Updatebyref(ref string valeur)
      {
            valeur="azstar;version par ref ";
       }
    si on fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //par valeur
    string value="Walo";
    Updatebyval(value);
    //ICI la valeur de value restera toujours "Walo"
    Updatebyref(ref value);
    //ICI la valeur changera et sera "azstar;version par ref "
    j’espère que c'est clair

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 002
    Points : 552
    Points
    552
    Par défaut
    Citation Envoyé par -N4w4k- Voir le message
    Donc tu perds quoi en passant un paramètre par référence? du temps? des infos? de la ressource?
    Tu perds rien, il peut simplement changer de valeur
    C’était le but de mon exemple.

  8. #8
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    D'après ce que j'ai compris les types valeurs c'est leur valeurs stockées tel quel en mémoire avec lequel tu travail, alors que les types par référence c'est un pointeur vers l'objet en mémoire.

    Donc quand tu copie un type valeur c'est cette valeur que tu copie à un autre emplacement mémoire, alors que pour le type par référence c'est le pointeur que tu copie résultat ce pointeur pointe toujours au même endroit.

    PS: le string à un fonctionnement assez particulier.

  9. #9
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Citation Envoyé par alavoler Voir le message
    Tu perds rien, il peut simplement changer de valeur
    C’était le but de mon exemple.
    Ah ok En tout cas j'aime assez ton impro qui parle de tunes et de string
    J’ai des questions à toutes vos réponses!

  10. #10
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour ezrider


    Attention au Passage par defaut (sans specification precise dans l'Appelant le Caller):
    - les types valeus sont passes par Valeur...
    - les types references sont passes Reference...

    doc MSDN rubrique
    Passage par référence et Passage par valeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Par défaut, lorsqu'un type valeur est passé à une méthode, une copie est passée plutôt que l'objet lui-même.Par conséquent, les modifications apportées à l'argument n'ont aucun effet sur la copie d'origine dans la méthode d'appel.....(plus loin)....
    Les types référence sont passés par référence. Lorsqu'un objet d'un type référence est passé à une méthode, la référence pointe vers l'objet d'origine, et non vers une copie.Les modifications apportées par le biais de cette référence seront par conséquent répercutées dans la méthode d'appel
    Sur un plan pratique et terre à terre :
    - si tu veux passer un type Valeur (entier,double,boolean ) par Reference utilise la double specification [IN,OUT] ...car c'est un type valeur....
    - inversement si tu veux passer un type Reference (class,array ) par Valeur utilise la specification [IN] ...car c'est un type Reference....

    bon code.............

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    C'est un sujet assez délicat, sur lequel même des développeurs expérimentés se mélangent souvent les pinceaux...

    Attention de ne pas confondre deux notions qui peuvent sembler similaires mais sont en fait tout à fait différentes et indépendantes :
    - la différence entre types valeur et types référence
    - la différence entre le passage par valeur et le passage par référence

    Cet article explique assez bien ces notions

    Citation Envoyé par alavoler Voir le message
    Le String de ta copine est un bel Objet et fait exception, il se comporte comme un type primitif, en effet le sacré vicelard qui a écrit la Framework, a redéfinit l'opérateur de copie, pour que le passage du String se fasse par valeur et non par référence! Du coup ta copine est sûr de ne jamais le perdre, ni même qu'il ne rétrécisse en le passant à la machine !
    Non. Il faut arrêter avec ce "mythe" selon lequel string serait un cas particulier ; c'est un type référence, qui fonctionne comme tous les types références. Sa seule particularité, c'est qu'il est immuable (pas modifiable), ce qui fait qu'on peut généralement le traiter de la même façon que les types valeur.
    D'autre part il n'y a pas "d'opérateur de copie"... Je suppose que tu fais référence à l'opérateur d'affectation (=), mais il fonctionne pour string comme pour tous les autres types référence...

    Citation Envoyé par MABROUKI Voir le message
    Attention au Passage par defaut (sans specification precise dans l'Appelant le Caller):
    - les types valeus sont passes par Valeur...
    - les types references sont passes Reference...
    Non, pas du tout. Par défaut, tous les types sont passés par valeur, y compris les types référence. Tu fais justement la confusion que j'ai mentionnée plus haut...

  12. #12
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour tomlev

    Mmh... ce n'est pas moi qui confond...c'est probablement la doc MSDN VS2010 qui fait des siennes .Qu'en penses-tu?
    Parce que je fais que la citer (je m'y suis refreree)....

    bonne journee......

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut
    -----

    La confusion survient surtout lorsqu'on passe un type référence par référence.

    Par défaut, comme Tomlev l'a bien expliqué, on passe les types références par valeur. En fait, ça revient à opérer une simple indirection:

    Si on a une variable "monobjet" de type référence, monobjet contient le pointeur vers l'objet lui-même (le contenu de l'objet).

    Lorsqu'on modifie une propriété de "monobjet", on modifie le contenu de ce qui est pointé par "monobjet": c'est une indirection simple.

    Si on modifie "monobjet" lui-même, par exemple avec "monobjet = new...." ou "monobjet = null", etc, alors on modifie le pointeur, et donc sur ce vers quoi il pointe. "monobjet" ne référencie plus le même objet.

    Si on passe "monobjet" à une méthode, par exemple, on passe par défaut par valeur, c'est à dire qu'on copie (c'est important) la valeur du pointeur et qu'on passe cette copie à la méthode. Admettons que cette méthode affecte cette copie au nom de variable "monobjet2", genre :

    public void method (objetType monobjet2)
    {...}


    On se retrouve avec la situation suivante:

    - monobjet : pointe sur le contenu de l'objet
    - monobjet2 : est une copie de monobjet et donc pointe sur le contenu de l'objet

    Si maintenant on modifie dans la méthode une propriété de "monobjet2", alors on va modifier l'objet pointé. Vu que cet objet est le même que celui pointé par "monobjet" dans la routine appelante, les modifications seront répercutées sur le contenu pointé par "monobjet" et donc par ce qu'on peut dire sur "monobjet" dans la routine appelante.

    MAIS si maintenant, dans la méthode, on affecte une nouvelle valeur à "monobjet2", que se passe-t-il?

    en fait, monobjet2 contenait une COPIE de monobjet (une copie du pointeur). Donc, si on écrit : monobjet2 = new objettype()..., on va REMPLACER la valeur de monobjet par une nouvelle.
    Or, la valeur de monobjet c'est un pointeur et non le contenu de l'objet, et donc c'est une référence vers le contenu de monobjet. On se retrouve donc avec la situation suivante:

    - monobjet pointe sur l'objet "monobjet"
    - monobjet2 pointe sur un autre objet

    Moralité, en modifiant une propriété de monobjet2 dans la méthode appelée, on ne modifie plus l'objet pointé par monobjet dans la méthode appelante, et donc on travaille sur 2 objets distincts. Les modifications sur monobjet2 ne se répercuteront plus sur monobjet "passé" en paramètre.

    Dit autrement, il est impossible avec un passage par valeur de modifier l'objet lui-même, on peut uniquement modifier son contenu.

    monobjet2 = null ne rend pas monobjet null
    monobjet2 = new objettype() ne modifie pas l'objet pointé par monobjet

    Maintenant, si on passe le type référence par référence, que se passe-t-il?

    Ben, en réalité on opère une double indirection. En effet, plutôt que de passer une copie du pointeur pointant sur le contenu de monobjet, on passe un pointeur sur le pointeur pointant sur le contenu de monobjet.

    Dit autrement:
    Par valeur, monobjet et monobjet2 pointent sur le contenu d'un objet
    var référence: monobjet2 pointe sur monobjet1 qui pointe sur le contenu d'un objet.

    Maintenant, que se passe-til si on modifie une propriété de monobjet2 dans la méthode appelée?

    On va en fait récupérer l'adresse de monobjet à partir de monobjet2, puisque monobjet2 pointe sur monobjet alors que dans le cas précédent il pointait directement vers le contenu de l'objet.

    Ensuite, on va pointer sur le contenu de monobjet via le pointeur "monobjet".
    Et, au final, on va modifier l'objet pointé par monobjet, qui est le même que l'objet pointé par monobjet2.

    Moralité, à ce niveau, rien ne change, sauf qu'on opère une double indirection, invisible pour l'utilisateur, pour accéder au contenu de monobjet.

    La où ça change, c'est si on se met à modifier l'objet référencé double-indirectement par monobjet2.

    En effet, si maintenant on écrit monobjet2 = new objettype(), que se passe-t-il?

    En fait, monobjet2 est un pointeur pointant sur monobjet, et donc lorsqu'on va écrire ça, on va créer un nouvel objet donc le pointeur va être retourné non pas à monobjet2, mais à ce qui est pointé par monobjet2. Or, ce qui est pointé par monobjet2, c'est le pointeur monobjet.

    Moralité, on récupère le pointeur sur le nouvel objet et on affecte la valeur de ce pointeur à l'objet pointé par monobjet2, et donc à monobjet.
    Donc monobjet dans la routine appelante pointe maintenant sur le nouvel objet et plus sur l'ancien. Et vu que monobjet2 pointe sur monobjet qui pointe sur le nouvel objet, monobjet2 référence aussi le même objet.

    Passer un type référence par référence est donc l'unique moyen de modifier non seulement le contenu de l'objet pointé, mais également l'objet pointé lui-même, tout simplement parce qu'on opère une double indirection qui est nécessaire dans ce cas particulier.

    Le passage par "out" n'est qu'un passage par référence classique, la seule différence est qu'on signale au compilateur chargé de vérifier la syntaxe que l'initialisation de l'objet pointé se fait dans la méthode appelée plutôt que classiquement dans la méthode appelante.

    Si maintenant les types références n'étaient pas passés par valeur par défaut, on ne pourrait pas écrire par exemple:

    var button = new Button();
    .. button.xxx= xxx
    .. button.xxx= xxx
    this.Add(button)
    button = new Button();
    .. button.xxx= xxx
    this.Add(button)

    car la deuxième création d'un bouton, affecté à la même variable, affecterait le bouton déjà ajouté à la fenêtre. Comme le passage est fait par valeur, il s'agit en fait de 2 boutons différents (mais on a perdu la référence sur le premier bouton).

    Raisonner avec un type variable est exactement identique mais en plus simple. Au lieu de 1 indirection (passage par valeur) ou 2 (passage par référence) on a respectivement 0 et 1 indirection.

    A+
    Claude

  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par MABROUKI Voir le message
    Mmh... ce n'est pas moi qui confond...c'est probablement la doc MSDN VS2010 qui fait des siennes .Qu'en penses-tu?
    Parce que je fais que la citer (je m'y suis refreree)....
    Je ne retrouve pas ce passage dans la doc MSDN ; pourrais-tu donner le lien ?

    En tous cas, il n'y a absolument aucun doute sur le fait que, sauf mention contraire (utilisation du mot-clé ref), les paramètres sont toujours passés par valeur par défaut. C'est valable même pour des types référence : la valeur de la variable est une référence, qui est passée par valeur.

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 002
    Points : 552
    Points
    552
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Non. Il faut arrêter avec ce "mythe" selon lequel string serait un cas particulier ; c'est un type référence, qui fonctionne comme tous les types références. Sa seule particularité, c'est qu'il est immuable (pas modifiable), ce qui fait qu'on peut généralement le traiter de la même façon que les types valeur.
    D'autre part il n'y a pas "d'opérateur de copie"... Je suppose que tu fais référence à l'opérateur d'affectation (=), mais il fonctionne pour string comme pour tous les autres types référence...
    Zut va falloir que je revoie mon texte alors !

    Petite question: ( j en profite vu que tu t es penché sur le sujet)
    Avec reflector / ilspy dans l implémentation de String qu'est ce qui fait qu il est immuable ?

  16. #16
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour à tous

    Voici le topic (english) ou j'ai pris la malheureuse citation:

    http://www.google.fr/url?q=http://ms...9Qo4hIB0EonyBw

    Le paragraphe cite s'intitule :
    Passing by Reference vs. Passing by Value
    By default, when a value type is passed to a method, a copy is passed instead of the object itself.
    plus loin ....
    When an object of a reference type is passed to a method, a reference to the object is passed. That is, the method receives not the object itself but an argument that indicates the location of the object. If you change a member of the object by using this reference, the change is reflected in the argument in the calling method, even if you pass the object by value.
    et le code .cs suivant illustratif:
    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
     
    public class SampleRefType
    {
        public int value;
    }
    public static void TestRefType()
    {
        SampleRefType rt = new SampleRefType();
        rt.value = 44;
        ModifyObject(rt);
        Console.WriteLine(rt.value);
    }
    static void ModifyObject(SampleRefType obj)
    {
        obj.value = 33;
    }
    et ce commentire sybyllin le suit:

    The example does essentially the same thing as the previous example in that it passes an argument by value to a method. But, because a reference type is used, the result is different. The modification that is made in ModifyObject to the value field of the parameter, obj, also changes the value field of the argument, rt, in the TestRefType method. The TestRefType method displays 33 as the output.
    et ici le meme topic MSDN fr ou j'ai relu pour m'assurer avant de poster :

    http://www.google.fr/url?q=http://ms...B8SSI3Gu38Guyw



    bonne soiree........

  17. #17
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par alavoler Voir le message
    Avec reflector / ilspy dans l implémentation de String qu'est ce qui fait qu il est immuable ?
    Avec Reflector tu n'y verras pas grand chose, parce que le type String est en grande partie implémenté directement dans le CLR, donc pas en code managé...
    En gros, il est immuable tout simplement parce qu'il n'existe aucun moyen de modifier les caractères qui composent la chaine (*) ; une fois initialisée, une instance de String contiendra toujours la même chaine.


    (*) en fait c'est possible, mais en "trichant", avec du code unsafe par exemple... mais bon, quand on commence à faire du unsafe, il n'y a pratiquement plus aucune garantie sur quoi que ce soit...

    Citation Envoyé par MABROUKI Voir le message
    Voici le topic (english) ou j'ai pris la malheureuse citation:

    http://www.google.fr/url?q=http://ms...9Qo4hIB0EonyBw
    Je pense que tu as mal interprété ce qui est dit dans cette page... il faut dire que ça prête un peu à confusion.

    By default, when a value type is passed to a method, a copy is passed instead of the object itself.
    Ici pas d'ambiguité, il s'agit simplement du passage par valeur d'un type valeur

    When an object of a reference type is passed to a method, a reference to the object is passed.
    A mon avis c'est cette phrase qui t'a induit en erreur : une référence à l'objet est passée, mais ça ne veut pas dire que l'objet est passé par référence ! Pour une variable de type référence, la valeur de la variable est une référence ; quand tu la passes en paramètre à une méthode (sans le modificateur ref), cette référence est passée par valeur. La méthode reçoit une copie de la référence, et affecter une autre référence au paramètre à l'intérieur de la méthode ne modifiera pas ce que voit l'appelant. Par contre, si la méthode modifie les propriétés de l'objet via le paramètre, ces modifs seront visibles par l'appelant, puisqu'il s'agit toujours du même objet

    Voilà une petite analogie un peu bête, mais relativement juste :

    - Passage par valeur d'un type référence :
    Je promène mon chien en laisse. Je veux que tu puisses aussi promener mon chien. Je te donne donc une autre laisse attachée au collier du même chien. Si tu décides de tondre le chien qui est au bout de la laisse, c'est bien mon chien qui est tondu ; mais si tu détaches la laisse pour l'attacher à un autre chien, ça ne change rien pour moi : j'ai toujours mon chien à moi au bout de ma laisse, et tu ne peux pas changer ça.

    - Passage par référence d'un type référence :
    Je ne veux pas promener mon chien, je veux que tu le fasses à ma place. Je te donne donc ma laisse attachée à mon chien (la mienne cette fois, pas une autre laisse). A la fin de la promenade, tu me ramènes ma laisse, mais rien ne garantit que c'est toujours mon chien qui est au bout : ça pourrait être un autre chien, ou pas de chien du tout... puisque tu avais la laisse, tu pouvais faire ce que tu voulais avec

    (au cas où ça ne serait pas clair : dans cet exemple, le chien est l'objet, les laisses sont les variables, et le fait de tondre le chien est une modification de l'état de l'objet)

    Citation Envoyé par MABROUKI Voir le message
    et ce commentire sybyllin le suit:
    Toujours pareil : l'objet est modifié (plus exactement : son état est modifié), mais la variable pointe toujours sur le même objet qu'avant : c'est bien un passage par valeur, pas par référence (même si c'est une référence qui est passée par valeur)

  18. #18
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Pro

    J'essaierais de me souvenir de cette histoire de chien et de laisse. C'est assez parlant.
    J’ai des questions à toutes vos réponses!

Discussions similaires

  1. Passage d'argument par référence (String et StringBuffer)
    Par dword2add dans le forum Débuter avec Java
    Réponses: 9
    Dernier message: 18/03/2008, 16h50
  2. Passage d'arguments par valeur et adresse
    Par ToutEnMasm dans le forum C++
    Réponses: 12
    Dernier message: 04/10/2007, 09h32
  3. Conteneurs STL : passage d'arguments par référence
    Par bolhrak dans le forum SL & STL
    Réponses: 0
    Dernier message: 26/09/2007, 20h54
  4. Passage d'arguments par référence
    Par Xavier44214 dans le forum Langage
    Réponses: 5
    Dernier message: 12/04/2007, 14h08
  5. Passage des arguments par valeur
    Par mpereg dans le forum Général Python
    Réponses: 4
    Dernier message: 13/03/2007, 17h12

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