Partage
  • Partager sur Facebook
  • Partager sur Twitter

C# Notion de POO { get;set;}

    14 février 2020 à 10:29:18

    Bonjour j'ai un petit problème de compréhension de cette notion, je m'explique.

    Dans un premier temps on nous à appris sur le cours POO la notion de "variables membres" et qu'il était conseillé de les mettre en privé c.a.d faire un:

     private int Ma_Variable;

    et après pour pouvoir y accéder faire une propriété derrière défini de la sorte:

    public int Ma_Propriété

    {

       get

       {

          return Ma_Variable

       }

       set

       {

         Ma_Variable = value;

       }

    }

    Cette structure est automatiquement généré sur Visual studio avec le mot : "propfull", et effectivement quand on tape ce mot, il génère bien tous c.a.d

    il génère la variable en private, qui sera effectivement réutiliser dans la propriété ce qui donne ca:

    private int myVar;

    public int MyProperty

    {

         get { return myVar; }

         set { myVar = value; }

      }

    ( et jusqu’à la je suis d'accord c'est totalement logique et raccord avec le cours).

    Mon problème survient quand on condense l’écriture, ce qui donne cette forme:

    public int Ma_propriété {get;set;}

    Là tous s'embrouille dans mon esprit, en fait la vrai question que je me pose est, OU EST MA VARIABLE MEMBRE avec cette écriture ? 

    Parce-que moi si je veux appeler ma variable membre "patate" par exemple, je fais comment moi ? hein ? mdrr

    et comment il sait du coup ce qu'il faut mettre dans get et value si on a pas de variables membres ? ou bien le Ma_propriété devient lui même sa propre variable membre ? 

    Bon je sais pas si mon explication de mon incompréhension est claire mais si vous pouvez m'apporter un peu d'aides ce serait cool merci d'avance 

    • Partager sur Facebook
    • Partager sur Twitter
      14 février 2020 à 12:28:21

      >Bon je sais pas si mon explication de mon incompréhension est claire

      Oui, c'est normal, car on vous a donnez des "règles" un peu trop simplistes et qu'il manque l'aspect "historique" de la chose.

      Bin, déjà, "variable membre", c'est une dénomination foireuse dont l'origine ne me semble pas familière, étrangement.

      Généralement, ce genre de dénomination approximative vient de prof. "spécialistes" d'autres langages et qui veulent imposer leur dénomination "approximative" a un langage qu'il ne maitrise pas assez.

      Mon background : C->C++->JAVA->C#, fait que j'appelle cela des "champs" ou des "champs membre" quand la notion de statique vient dans le scope.

      L'une des 3 règles de la POO est l'encapsulation.

      C'est généralement l'un des règles qui passe le plus facilement, mais on a tendance à l'utiliser à tort et à travers.

      Le principe de l'encapsulation en POO, c'est de ne pas fournir de détail de l'implémentation interne d'un objet, pour facilement faire évoluer son implémentation sans avoir à revenir sur le code client de cet objet.

      Mais si vous faites une classe "Point2D", par exemple, dont le seul but est de stocker ensemble une abscisse x et une ordonnée y, il est complètement insensé de créer 2 propriétés x et y (avec les 2 champs qui vont avec) juste pour ça. "x" et "y" ne sont pas des détails d'implémentation mais des éléments de l'API de la classe.

      Si vous voulez que votre classe "Point2D" puisse gérer à la fois des coordonnées cartésiennes et des coordonnées polaires, cela change tout et l'utilisation de propriétés x,y,r et phi devient pertinente. Vous n’aurez alors pas un simple mapping une propriété<=>un champ. Dans ce cas de figure l'implémentation des "setter" et des "getter" n'est pas triviale. Bon, elle casse pas 3 pattes à un canard mais cela justifie l'usage de propriétés et non de champs. On pourra peut-être la nommé "Point2DOrthoPolaire" si vous devez avoir ces 2 types de classe dans le même projet.

      Mais cela explique pourquoi on peut, en C#, aussi bien utiliser des champs ou des propriétés en fonction des besoins.

      Il faut bien comprendre que les propriétés C# n'est qu'un "syntaxical sugar".

      private int myVar;
      
      public int MyProperty
      {
           get { return myVar; }
           set { myVar = value; }
      }

      et traduit par le compilateur par :

      private int myVar;
      
      public int _@%get_MyProperty_PleinDeTrucChelouPourNePasAvoirDeColisionDeNom()
      {
           return myVar; }
      }
      
      public _@%set_MyProperty_PleinDeTrucChelouPourNePasAvoirDeColisionDeNom(int value)
      {
           myVar = value; }
      }


      Il fait le même tour de passe-passe lors de l'utilisation des propriétés.

      Ce n'est pas une figure de l'esprit, c'est vraiment comme ça, cf. le code IL généré.

      Ça, c'est l'état des lieux en .NET1.0 (année 2000).

      On passe à l'histoire de la version "condense", comme vous dite.
      Si vous avez bien compris, l'utilisation intelligente des propriétés permet de maintenir la cohérence des données internes de la classe (prendre exemple sur la classe "Point2DOrthoPolaire" ci-avant). Il est donc très probable que même pour l'implémentation interne, vous utilisez les propriétés et pas les champs pour bénéficier de ces avantages sur la maintenance de la cohérence des données internes.

      Donc, si vous faites ça bien, vous vous retrouvez avec une propriété que vous utilisez partout, aussi bien dans le code client de votre classe que dans l'implémentation interne de la classe. Mais vous vous retrouvez aussi avec un champ, et qui n'a aucun avantage à être utilisé (sauf à contourner la vérification de la cohérence des données, donc ça sent pas bon).

      Il est donc, dans ces conditions, plus pertinent de "cacher" ce champ qui poserait systématiquement problème à chaque utilisation. Soit vous faites les mêmes vérifications de cohérence que dans la propriété à chaque utilisation de ce champ, soit vous contournez ces vérifications et c'est le bordel dans la classe.

      En "cachant" ce champ, vous avez un code plus sûr "naturellement" et, cerise sur le gâteau, plus simple et plus concis.

      Comme il la fait pour la génération des méthodes membres pour simuler des propriétés, le compilateur crée pour vous un champ, avec un nom à coucher dehors pour que vous n'ayez aucune chance d'en déclarer un vous-même de même nom, et génère le code des méthodes set et get de la propriété pour permet de stocker les valeurs dans ce champ "cacher".

      Cela permet d'avoir rapidement un code sûr et évolutif, car vous pouvez changer ou redéfinir facilement les implémentations des propriétés si l'implémentation triviale n'est plus adaptée, sans avoir à modifier le code interne de la classe.

      >Parce-que moi si je veux appeler ma variable membre "patate"

      Vous pouvez toujours le faire, en faisant du code à la .NET1.0, mais avez-vous vraiment besoin d'un champ "patate" et pas d'une propriété "Patate" qui maintient sa cohérence avec le reste de la classe "automatiquement ?

      >et comment il sait du coup ce qu'il faut mettre dans get et value si on a pas de variables membres ?

      Il y a un champ, mais il est "caché".

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        14 février 2020 à 14:02:57

        Merci beaucoup Bacelar pour ces explications, effectivement, était (débutant*10000000) en développement, c’était pas assez évidant pour moi de faire ce tour d'esprit, après  j’espère qu'avec le temps ça deviendra plus naturel, mais merci encore pour les explications
        • Partager sur Facebook
        • Partager sur Twitter
          14 février 2020 à 14:50:23

          Salut,

          Dis en plus court, en C# la déclaration de la "variable membre" comme vous dites peut être implicite. A quoi bon de déclarer une variable private pour lui appliquer seulement des getters/Setters, en C# c'est un raccourcis.

          -
          Edité par thebastien007 14 février 2020 à 14:50:51

          • Partager sur Facebook
          • Partager sur Twitter
            14 février 2020 à 15:07:11

            >A quoi bon de déclarer une variable private pour lui appliquer seulement des getters/Setters, en C# c'est un raccourcis.

            C'est tellement évident qu'il a fallu attendre un truc comme C#4.0 et environ 10 ans (~2010) pour que tout le monde se rendent compte de cela. ;-)

            Moi, j'ai été aveugle et borné pendant ces 10 ans, alors je suis assez coolant avec les personnes qui prennent le train en marche.

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              17 février 2020 à 10:47:49

              Bon disons que moi en tant que de débutant je ne comprenais pas ou passais ma variable membre avec la technique du prop, alors qu'avec propfull tous s’affichait totalement
              • Partager sur Facebook
              • Partager sur Twitter

              C# Notion de POO { get;set;}

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown