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 :

non compréhension de this


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 371
    Par défaut non compréhension de this
    bonjour,

    Je ne comprends pas this
    Tout ce que je sais de this:
    -ne s'utilise que dans une classe
    0)Est=ce que je me trompe encore?

    Au fait,
    1)est-ce qu'il y a forcément un constructeur dans une classe?

    J'ai vu ceci à propos de this:
    https://docs.microsoft.com/fr-fr/dot.../keywords/this

    Dans la fonction Employee de la classe Employee,il y a écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     this.name = name;
     this.alias = alias;
    Avant la fonction,name et alias sont déclarés avec un type string
    3 questions m'interpellent alors dans la fonction:
    a)pourquoi le type n'est pas redonné?
    b)s'agit-il bien d'une affectation grâce à =?
    c)pourquoi y a-t-il redondance?(2X name et 2x alias)

    Les réponses m'éclairciront sur la compréhension de this


    merci de votre aide

  2. #2
    Membre Expert
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 661
    Par défaut
    Bonsoir,

    C'est un peu maladroit dans l'exemple mais le mot-clé this est très simple :

    Il permet de préciser qu'il s'agit de la variable membre de la classe, ce qui est utile dans le cas d'un paramètre de fonction du même nom présent dans une même portée, ce qui arrive souvent dans les constructeurs par exemple.

    Si il y a redondance, c'est parce qu'il y a justement le mot-clé this qui le permet. Inutile de trouver un nom alternatif pour chaque paramètre, this est là pour pas qu'on se prenne la tête de ce côté là. En général il est préférable de s'en tenir qu'à ce cas de figure, c'est à dire à l'affection de valeur. Et le plus souvent dans un constructeur. Dans les autres cas on préfère donner un nom qui précise qu'il s'agit d'une variable à courte portée.

    Pour tes questions :

    Le type est bien redonné, déclaré dans les paramètres. Et oui il s'agit bien d'une affectation.

    Non il n'y a pas forcément besoin d'un constructeur, chaque classe en a un par défaut, sans paramètres.

    Si jamais ça te perturbe trop, tu peux toujours utiliser une notation qui demande à a ce que les variables membre comment par _ ou m_, dans ces cas là, pas de this. Un petit recap' si jamais tu n'es pas allergique à l'anglais. => Lien

  3. #3
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 972
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 972
    Par défaut
    Je me permet d'apporter une précision.

    this est un mot clé qui s'utilise pour faire référence à l'instance actuelle de la classe.
    this équivaut donc à "moi-même".

    Lorsque tu écris "this.name", cela signifie que l'information est lue (ou stockée dans le cadre d'une affectation) dans un membre "name" situé dans "moi-même" et donc au sein même de la classe. Ce qui implique que tu auras un membre "name" déclaré quelque part dans la classe.

    Pour reprendre l'exemple que tu cites :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Employee
    {
        private string alias;
        private string name;
     
        public Employee(string name, string alias)
        {
            // Use this to qualify the members of the class
            // instead of the constructor parameters.
            this.name = name;
            this.alias = alias;
        }
    }
    est la déclaration du membre "name".
    Le mot clé "private" indique que ce membre ne sera pas accessible ailleurs quand dans cette classe.
    Le mot clé "string" est le type de ce membre
    Et "name" est le nom de ce membre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public Employee(string name, string alias)
    est la déclaration du constructeur de la class.
    On retrouve "string name", indiquant que ce constructeur prend un paramètre nommé "name" de type "string"
    On se retrouve donc avec un paramètre "name" et un membre privé "name" (donc avec le même nom).

    Puisque le paramètre et le membre privé ont le même nom, on ajoute le mot clé "this" (moi-même) pour différencier le membre privé (celui de moi-même) de celui qui est donné en en paramètre (qui vient d'ailleurs).
    Cette ligne dit donc, "Place le contenu de la chaine "name" issue de l'extérieur dans la chaîne "name" que je gère moi.

    Comme la très bien fait remarqué PixelJuice, on retrouve généralement cette syntaxe particulière dans les constructeur, et si on ne veut pas être obligé d'utiliser "this", il faut nommer le paramètre interne (celui qui est accessible via "this") d'une autre manière et la plupart des développeurs place un undescore devant.
    Comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Employee
    {
        private string _alias;
        private string _name;
     
        public Employee(string name, string alias)
        {
            _name = name;
            _alias = alias;
        }
    }
    Pour ma part, j'ai pris l'habitude de nommer "given", ce qui m'a été transmis par le constructeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Employee
    {
        private string givenAlias;
        private string givenName;
     
        public Employee(string name, string alias)
        {
            givenName = name;
            givenAlias = alias;
        }
    }
    Mais utiliser, "_name" ou bien "givenName" n'a aucune incidence sur le code.
    Il peut cependant arriver que deux personnes ne codent pas de la même façon.
    Et dans, ce cas le mieux est d'en discuter et de se tenir à la décision qui sera prise.

  4. #4
    Membre très actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 371
    Par défaut
    1)Pourquoi on n'écrit pas ceci?:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class Employee
    {
        private string  alias;
        private string  name;
     
        public Employee(string name, string alias)
        {
          string  _name = "gérard";
          string  _alias ="gege" ;
        }
    }
    car en C/C++,la déclaration d'une variable suivie de son affectation à l'intérieur d'une fonction se fait comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void ma_fonction(void)
      {
          int a=2;
          char b='f';
     }
    2)Si j'aivais écris comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class Employee
    {
        private string  alias;
        private string  name;
     
        public Employee(string name, string alias)
        {
          string  _name = name;
          string  _alias = alias;
        }
    }
    cela veut-il dire que:
    _name est affectée de la même affectation que name?
    _alias est affecté de la même affectation que alias?

    Si oui,alors je comprends que this est à utliser seulement si les variables de la fonctions membre ont le même nom que celles de la classe.
    Est-ce bien cela?

    2)Alors ensuite se pose une nouvelle question.
    Si on revient à cette écriture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class Employee
    {
        private string  alias;
        private string  name;
     
        public Employee(string name, string alias)
        {
          this.name = name;
          this.alias = alias;
        }
    }
    et que je veux réutiliser la variable de la fonction membre(en lui affectant une autre valeur),que dois-je écrire?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.name="albert";
    ?

    et si je veux réutliser la variable de la classe(en lui affectant une autre valeur),dois-je écrire:
    ?

    3)enfin,puis-je écrire comme ceci?:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    public class Employee
    {
        private string  alias;
        private string  name;
     
        public Employee(string name, string alias)
        {
          this.name = "gérard";
          this.alias = "gege";
        }
    }

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    1) ce code est autorisé, néanmoins les paramètres (string name, string alias) n'ont plus d'utilité ...

    2) oui, mais ici tu déclares des variables dans la méthode, les variables de méthodes sont effacées à la fin de celle ci, donc ce code n'aurait pas d'utilité en l'état

    2 bis) pas compris

    3) c'est la même chose que le 1 ...


    dans le cas suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    private string name;
    private string _name;
    private string alias;
     
    public Employee(string name)
    {
        name = name;
        this.name = name;
        _name = name;
        this._name = name;
     
        string alias = "a";  
     }
    name = name ne fait rien, il prend ce qu'il y a dans la variable name et le met dans la même variable, il y a à cet endroit du code 2 choses accessibles qui ont le même nom, c# va alors utiliser celui qui est déclaré au plus près
    tout comme dans cette méthode il y a 2 choses accessibles qui s'appellent alias, la variable de membre et la variable de classe, si on écrit juste son nom c# utilisera celle déclarée au plus près

    this.name = name, là this.name le force à utiliser la variable de classe

    _name = name, là il ne trouve qu'un _name et qu'un name donc on voit bien ce que ca fait (doù le fait que la plupart des développeurs préfèrent des variables de classent en _name)

    this_name = name est identique à _name = name

    des fois on tape this. pour avoir l'intellisense (autocomplétion) qui ne recherche que ce qui est dispo sur la classe
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 972
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 972
    Par défaut
    Pourquoi on n'écrit pas ceci?:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Employee
    {
        private string  alias;
        private string  name;
     
        public Employee(string name, string alias)
        {
          string  _name = "gérard";
          string  _alias ="gege" ;
        }
    }
    Lorsque tu écris ceci, tu déclare deux membres privés "name" et "alias" qui seront accessible uniquement depuis ta classe mais tu les utilises pas.
    Ceci car ton constructeur déclare localement deux nouvelles variables "_name" et "_alias" qui seront perdues à la fin de l'exécution du code du constructeur (car locales).
    Cela est étroitement lié à la notion de portée des variables.
    https://docs.microsoft.com/fr-fr/dot...tion/variables

    Les variables "_name" et "_alias" sont locales car tu as mis le type "string" devant.
    Si tu avais enlevé le terme "string", tu aurais utilisé une variable de classe (accessible par this) mais tu aurais obtenu une erreur de compilation car ces variables ne sont pas déclarées dans la classe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Employee
    {
        private string  alias;
        private string  name;
     
        public Employee(string name, string alias)
        {
          string  _name = name;
          string  _alias = alias;
        }
    }
    cela veut-il dire que:
    _name est affectée de la même affectation que name?
    _alias est affecté de la même affectation que alias?
    Oui
    _name va prendre la valeur de name
    _alias va prendre la valeur de alias
    Mais puisque que _name et _alias sont locales, elle seront perdues.

    Si oui,alors je comprends que this est à utliser seulement si les variables de la fonctions membre ont le même nom que celles de la classe.
    Est-ce bien cela?
    Oui et non.
    Oui dans le cas bien particulier de l'utilisation de this dans le constructeur.
    Non car this est également utilisé lorsque tu écrit une méthode d'extension ou en tant que référence lors d'un appel à une routine prenant un paramètre de même type que ta classes (ou un type ancêtre de ta classe).

    Si on revient à cette écriture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Employee
    {
        private string  alias;
        private string  name;
     
        public Employee(string name, string alias)
        {
          this.name = name;
          this.alias = alias;
        }
    }
    et que je veux réutiliser la variable de la fonction membre(en lui affectant une autre valeur),que dois-je écrire?
    ?
    Tu peux écrire 'this.name = "albert";'
    Mais dans ce cas, le paramètre name du constructeur n'est plus utilisé et ne sert donc plus à rien.

    et si je veux réutliser la variable de la classe(en lui affectant une autre valeur),dois-je écrire:
    ?
    Oui à condition que tu enlèves le paramètre name dans la signature du constructeur.
    Sinon tu va changer la valeur du paramètre, pas cellle du membre de ta classe.

    enfin,puis-je écrire comme ceci?:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Employee
    {
        private string  alias;
        private string  name;
     
        public Employee(string name, string alias)
        {
          this.name = "gérard";
          this.alias = "gege";
        }
    }
    Rien n'interdit d'écrire ceci mais il faut en saisir toutes les implications.
    Avec ce code tous les employés vont par défaut s'appeler "gérard".
    Avec ce code les paramètres name et alias de ton constructeur ne sont pas utilisés et donc inutiles (alors autant les enlever), et si tu les enlèves, tu ne pourra pas les confondre avec les membres de ta classes et this devient inutile.

Discussions similaires

  1. non compréhension de this
    Par tabkelm dans le forum Débuter
    Réponses: 8
    Dernier message: 10/11/2021, 14h11
  2. Réponses: 3
    Dernier message: 23/09/2009, 10h33
  3. Réponses: 3
    Dernier message: 12/01/2007, 09h42
  4. [Linkage] Non compréhension d'erreur
    Par GLDavid dans le forum VC++ .NET
    Réponses: 6
    Dernier message: 04/01/2007, 14h58
  5. [FOP] [ERROR] non-static variable this cannot be referenced from a static context
    Par cash3000 dans le forum API standards et tierces
    Réponses: 8
    Dernier message: 05/05/2006, 16h46

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