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

 .NET Discussion :

paramètre de type out


Sujet :

.NET

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    958
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 958
    Points : 141
    Points
    141
    Par défaut paramètre de type out
    Bonjour,
    Un paramètre output est il considéré comme un paramètre de type référence ou de type value.

    En effet j'ai un doute depuis que j'ai ou ceci à propos des indexers

    Quand on appelle une méthode qui prend un paramètre de type ref(reference) ou out, on passe une adresse mémoire à la méthode.
    Les éléménts d'un array se rapportent directement à des adresses mémoire et donc peuvent être utilisés en tant que paramètres de type ref ou out.
    Les indexers ne se rapportent directement à des adresses mémoire, et on ne peut les utiliser en tant que paramètres de type ref ou out mais les utiliser en tant que paramètre de type VALUE.
    S'il un paramètre output est de type référence que se passe-til quand il est de type int:y-a-t-il un boxing qui s'effectue?

    comme par exemple dans ce cas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int value;
    MyMethod(10,101.1F,out value);
     
    Je vous remercie beaucoup de votre réponse.
     
    Cordialement.
     
    new_wave
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. [SHADOKS]

  2. #2
    Membre éclairé Avatar de chamamo
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    588
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 588
    Points : 735
    Points
    735
    Par défaut
    Le paramètre out comme le paramètre ref sont traités de la même façon, on passe la référence, sans ce paramètre ce que tu passes à la méthode est la copie de la variable, donc tout ce que tu fais sur celle-ci ne sera pas appliqué à la valeur originale, comme tu l'as cité on passe l'adresse mémoire, la seule différence entre les deux c'est que avec le ref on est obligé d'initialiser la variable avant de la passer, exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    //code correcte
    int i;
    MaMethode(out i);
     
    //Code incorrecte
    int i;
    MaMethode(ref i);
    S'il s'agit d'une variable de type référence, ça n'a pas de sens d'utiliser le out, car dans tous les cas tu vas passer la référence.

  3. #3
    Membre chevronné

    Profil pro
    Chef de Projet / Développeur
    Inscrit en
    Juin 2002
    Messages
    599
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de Projet / Développeur
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2002
    Messages : 599
    Points : 2 024
    Points
    2 024
    Par défaut
    Citation Envoyé par chamamo Voir le message
    S'il s'agit d'une variable de type référence, ça n'a pas de sens d'utiliser le out, car dans tous les cas tu vas passer la référence.
    out n'a aucun intérêt au niveau du code généré, mais il évite les erreurs de programmation dès le compilateur, en permettant à celui-ci de faire certains contrôles.

    Le compilateur oblige la méthode appelée à modifier la variable.
    C'est un peu comme le warning qui prévient qu'une fonctionne ne fait pas de return dans tous les chemins de l'algorithme.

    Idem pour l'appelant, le fait de l'obliger à spécifier le mot "out" lors de l'appel, lui indique que l'appel par référence n'est pas une optimisation ou nécessité d'écriture, mais que le paramètre est bel et bien une variable de sortie et que sa valeur va donc forcement être modifiée.
    --
    vanquish

  4. #4
    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 new_wave Voir le message
    Un paramètre output est il considéré comme un paramètre de type référence ou de type value.
    En fait il n'y a pas de lien entre le fait que ce soit un paramètre normal, ref ou out, et le fait qu'il soit de type valeur ou référence. Ce sont deux concepts distincts. On peut :
    • passer par valeur un paramètre de type valeur
    • passer par valeur un paramètre de type référence (dans ce cas la valeur du paramètre est une référence)
    • passer par référence un paramètre de type valeur
    • passer par référence un paramètre de type référence


    EDIT: voir cet article :
    http://tlevesque.developpez.com/tuto...metres-csharp/

    Citation Envoyé par new_wave Voir le message
    S'il un paramètre output est de type référence que se passe-til quand il est de type int:y-a-t-il un boxing qui s'effectue?
    Non, pas de boxing

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    958
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 958
    Points : 141
    Points
    141
    Par défaut
    Bonjour,

    Je souhaiterais revenir sur ton article "passage de paramètres en C#" et en particulier sur le chapitre
    "Parenthèse : quelle est la différence entre passer un objet valeur par référence et passer un objet référence par valeur"

    Tu donnes l'exemple suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void Foo(??? IntHolder x)
    {
        x = new IntHolder();
    }
     
    ...
     
    IntHolder y = new IntHolder();
    y.i = 5;
    Foo(??? y);
    Tu écris

    Dans le cas où IntHolder est une structure (donc un type valeur) et où le paramètre est passé par référence (c'est-à-dire qu'on remplace ??? par ref ci-dessus),
    y devient une nouvelle valeur IntHolder - c'est-à-dire que y.i vaut 0"
    Que signifie que y devient une nouvelle IntHolder?
    Cela signifie -t-il que le paramètre y va maintenant contenir une adresse mémoire qui est celle de l'objet de type structure crée à l'instruction
    IntHolder y = new IntHolder();
    et non plus la structure elle même; puis cette adresse mémoire va être affectée au paramètre x.

    Puis quand sera appelée la méthode Foo, y va pointer vers un nouvel objet car la variable x va contenir une adresse(reference) et non une copie de structure?

    Je te remercie beaucoup de bien vouloir m'aider à comprendre ce que tu as voulu dire.

    Bien cordialement.

    new_wave
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. [SHADOKS]

  6. #6
    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 new_wave Voir le message
    Je souhaiterais revenir sur ton article "passage de paramètres en C#"
    C'est pas mon article, je l'ai juste traduit

    Citation Envoyé par new_wave Voir le message
    Que signifie que y devient une nouvelle IntHolder?
    Ca signifie qu'une nouvelle instance de IntHolder est affectée à y. Si IntHolder est une structure, la nouvelle instance écrase l'ancienne, en réutilisant le même emplacement mémoire.

    Citation Envoyé par new_wave Voir le message
    Cela signifie -t-il que le paramètre y va maintenant contenir une adresse mémoire qui est celle de l'objet de type structure crée à l'instruction
    IntHolder y = new IntHolder();
    et non plus la structure elle même; puis cette adresse mémoire va être affectée au paramètre x.

    Puis quand sera appelée la méthode Foo, y va pointer vers un nouvel objet car la variable x va contenir une adresse(reference) et non une copie de structure?
    Non, pour un type valeur, la variable contient directement l'objet, pas son adresse. Quand tu passes la variable par référence, c'est son adresse qui est passée, mais dans la méthode appelée, le paramètre fait référence à l'objet lui-même.

    Si tu as déjà fait du C, tu peux imaginer que ref y est équivalent à &y. Le code C équivalent à l'exemple serait quelque chose comme ça (désolé pour les éventuelles erreurs de syntaxe, ça fait un moment que j'ai pas codé en C...) :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void Foo(IntHolder * x)
    {
        memset(x, 0, sizeof(IntHolder));
    }
     
    ...
     
    IntHolder y;
    y.i = 5;
    Foo(&y);
     
    // maintenant y.i vaut 0

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    958
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 958
    Points : 141
    Points
    141
    Par défaut
    Bonjour et merci de ta réponse que j'ai bien comprise.

    Je considère que le sujet est maintenant résolu.


    Bien cordialement.

    new_wave
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. [SHADOKS]

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    958
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 958
    Points : 141
    Points
    141
    Par défaut paramètre de type ref
    Bonjour,

    Je reviens vers toi concernant le dernier mail que tu m'as envoyé pour m'expliquer que ref y est équivalent à &y.

    Dans ton exemple de fonction FOO, il, est écrit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     
    void Foo(IntHolder * x)
    {
        memset(x, 0, sizeof(IntHolder));
    }
    Tu expliques ainsi qu'à l'adresse y est créée une nouvelle structure(memset permet de l'allocation mémoire pour la création de cette structure, si j'ai bien compris).
    Cependant, IntHolder * x , l'argument de la fonction FOO, est un pointeur, alors que &y, la valeur effective, est une constante qui représente l'adresse de y et non un pointeur.
    Peux tu m'expliquer pourquoi tu as pu donner à IntHolder * x une valeur effective qui n'est pas un pointeur.

    Je te remercie encore de ton aide à la compréhension de cette notion.

    Bien cordialement.

    new_wave
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. [SHADOKS]

  9. #9
    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 new_wave Voir le message
    Tu expliques ainsi qu'à l'adresse y est créée une nouvelle structure
    Non, je n'ai pas dit ça...

    Citation Envoyé par new_wave Voir le message
    (memset permet de l'allocation mémoire pour la création de cette structure, si j'ai bien compris).
    Non, memset initialise une zone mémoire à la valeur spécifiée ; la mémoire est déjà allouée avant.

    Citation Envoyé par new_wave Voir le message
    Cependant, IntHolder * x , l'argument de la fonction FOO, est un pointeur, alors que &y, la valeur effective, est une constante qui représente l'adresse de y et non un pointeur.
    pointeur = adresse, c'est pareil. Un pointeur est une variable qui contient une adresse. L'affectation suivante est donc parfaitement valide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IntHolder i = ...
    IntHolder * p = &i;
    "*" associé à un type signifie "pointeur vers ce type", autrement dit, une variable IntHolder* contient l'adresse d'un objet IntHolder. Et l'opérateur "&", appliqué à une variable de type IntHolder, donne l'adresse de l'objet.

    Citation Envoyé par new_wave Voir le message
    Peux tu m'expliquer pourquoi tu as pu donner à IntHolder * x une valeur effective qui n'est pas un pointeur.
    Justement parce qu'un pointeur est une adresse...

    Mais bon, là on s'écarte un peu de C#... j'avais donné une comparaison (approximative) avec C pour t'aider à comprendre au cas où tu aurais déjà fait du C, mais si ce n'est pas le cas, ça ne va pas t'aider, au contraire...

    En fait, le mot clé ref en C# a 2 sens :
    - déclarer un paramètre comme étant "par référence" (donc ref IntHolder x est équivalent à IntHolder * x en C)
    - passer une variable par référence à une méthode (donc ref y est équivalent à &y en C)

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    958
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 958
    Points : 141
    Points
    141
    Par défaut paramètre de type ref
    Bonsoir,

    J'ai bien repris tes explications, en particulier le fonctionnement de la fonction memset.
    Je n'avais en effet pas bien compris son fonctionnement.
    Le parallèle avec le langage C est intéressant et permet de bien comprendre , au contraire.
    Comme je n'ai pas pratiqué ce langage , j'ai repris son cours.

    Ce qui m'avait échappé , c'est qu'un paramètre de type pointeur peut recevoir en effet, en valeur effective une adresse puisque c'est ce qu'il peut contenir, tout comme une variable de type int peut seulement contenir une valeur de ce type.

    Je souhaite juste que tu me confirmes que lorsque on écrit dans la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Foo( ref intHolder x){
     
    x = new intHolder(); 
     
    }
    La structure qui existait à l'adresse y est remplacée à cette même adresse , par une nouvelle structure dont tous les champs sont initialisés à 0.


    S'il s'avère que j'ai bien compris, alors le sujet est définitivement résolu et je te remercie vivement encore de tes explications.

    Bien cordialement.

    new_wave
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. [SHADOKS]

  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
    Citation Envoyé par new_wave Voir le message
    Je souhaite juste que tu me confirmes que lorsque on écrit dans la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Foo( ref intHolder x){
     
    x = new intHolder(); 
     
    }
    La structure qui existait à l'adresse y est remplacée à cette même adresse , par une nouvelle structure dont tous les champs sont initialisés à 0.
    Oui, c'est ça

Discussions similaires

  1. ADO - Paramètres de type tableau
    Par npze dans le forum Bases de données
    Réponses: 10
    Dernier message: 19/10/2006, 14h40
  2. Paramètre de type inconnu
    Par Amoust dans le forum Bases de données
    Réponses: 3
    Dernier message: 07/08/2006, 08h20
  3. Réponses: 16
    Dernier message: 25/07/2006, 15h58
  4. Réponses: 10
    Dernier message: 21/04/2006, 18h23
  5. [ADO] Passage de paramètre de type Date dans une requête
    Par e-ric dans le forum Bases de données
    Réponses: 6
    Dernier message: 25/01/2006, 12h36

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