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 :

Conception objet - Constructeur


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 49
    Par défaut Conception objet - Constructeur
    Bonjour,

    Je fais un petit projet de gestion (très simple) de CDThèque, histoire de me familiariser avec l'objet, que je ne maîtrise pas.

    Je me heurte à un petit problème d'objet tout bête...Mais comme je manque d'expérience, je fais appel aux spécialistes.

    J'ai créé une classe "Song", qui contient les propriétés et méthodes liées à une chanson :

    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
    17
    18
    19
    20
    21
     
    private int _songId = "";
    private string _songName = "";        
    //...
     
    public int ID
    {
       get { return songId ; }
       set { songId  = value; }
    }
    public string Name
    {
       get { return _songName ; }
       set { _songName  = value; }
    }
    //...
     
    //Constructeur
    public Song()
    {
    }
    J'ai aussi créé une classe album, qui contient les propriétés et méthodes liées à un album :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    private int _albumId = "";
    private string _albumName = "";  
    private Song[] _albumSongs;      
    //...
     
    public int ID
    {
       get { return _albumId ; }
       set { _albumId = value; }
    }
    public string Name
    {
       get { return _albumName ; }
       set { _albumName = value; }
    }
    public Song[] Songs
    {
       get { return _albumSongs; }
       set { _albumSongs= value; }
    }
    //...
     
    //Constructeur
    public Album()
    {
    }
    public Album(int aId,string name)
    {
          this.ID=aId;      
          this.Name=name;
          GetSongs();      
    }
    public void GetSongs()
    {
          //Ici :
          //Requête qui ramène toutes les chansons de l'album dont l'id est : aId
          //Je mets le résultat de la requête dans une Hashtable lstSongs
         for (int i=0;i<lstSongs.Count;i=i+2)
         {
               this.Songs[i] = new Song();
               this.Songs[i].ID = lstSongs[i];
               this.Songs[i].Name = lstSongs[i +1];
         }
    }
    Mais je me fais jeter sur la ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      this.Songs[i] = new Song();
    Avec une erreur du type "La référence d'objet n'est pas définie à une instance d'objet."

    Voilà donc le problème.
    Je souhaite avoir un constructeur, qui à partir de l'ID de l'album, me charge dans mon objet Album la liste des chansons.
    Encore une fois, je ne suis pas à la recherche de la solution pour constituer un outil de gestion de CDThèque idéal, je me sers simplement de cet exemple pour combler mes -grosses!- lacunes en conception objet. Ce qui m'intéresse donc ici, c'est comment faire pour renseigner une "collection" avec des objets en somme...

    Merci d'avance pour tout conseil.

  2. #2
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Songs est un tableau. C'est à dire un objet qui en contient d'autres.

    Là, tu as essayé d'appeler une méthode de Songs (écrire machin[i] = bidule équivaut à appeler la méthode this[] de l'objet machin), alors qu'il est encore null. Et en objet, appeler une méthode sur une référence nulle lève une exception (de type NullRefeernceException).

    Tu dois donc, avant d'ajouter des éléments à Songs, l'initialiser, avec par exemple :
    this.Songs = new Song[10];
    si tu supposes que tous tes albums ont 10 chansons.

    Après, les tableaux (de la forme T[]) ont une taille fixe ; dans ton cas, tu devrais plutôt te tourner vers une List<Song>, qui est un conteneur de taille variable, auquel il te suffit de faire taListe.Add(taChanson). Il faut aussi bien sûr initialiser une liste avec taListe = new List<Song>().

  3. #3
    Membre Expert Avatar de Tober
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2007
    Messages
    824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 824
    Par défaut
    Si je ne dis pas de connerie, il faut d'abord instancie ton tableau Songs comme ca :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    Songs = new Song[lataillequetuveux];
    Je te conseil aussi de changer ton
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    private Song[] _albumSongs;
    en
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    private IList<Song> _albumSongs;
    car c'est plus facile a utiliser, tu peux ajouter des elements autant que tu veux, ...

    Edited : Mais euh copieur !

  4. #4
    Membre émérite
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Par défaut
    Utilise un foreach plutôt qu'un for c'est plus simple à utiliser (c'est un peu plus long mais bon on peut pas tout avoir ).

    EDIT: par contre ça je suis pas d'accord (erreur de manip peut être ?):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private int _albumId = "";

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 49
    Par défaut
    Merci Guulh et Tober pour la IList ! C'est effectivement très adapté à ce que je veux faire.

    Et harz62, bien vu pour l'erreur, il s'agit effectivement d'un copier-coller malheureux...

    Pour ceux que ça intéresse donc :

    Classe Song :

    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
    17
    18
    19
    20
    21
     
    private int _songId;
    private string _songName;        
    //...
     
    public int ID
    {
       get { return songId ; }
       set { songId  = value; }
    }
    public string Name
    {
       get { return _songName ; }
       set { _songName  = value; }
    }
    //...
     
    //Constructeur
    public Song()
    {
    }
    Classe Album :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    private int _albumId;
    private string _albumName;  
    private System.Collections.Generic.IList<Song> _albumSongs;      
    //...
     
    public int ID
    {
       get { return _albumId ; }
       set { _albumId = value; }
    }
    public string Name
    {
       get { return _albumName ; }
       set { _albumName = value; }
    }
    public System.Collections.Generic.IList<Song> Songs
    {
       get { return _albumSongs; }
       set { _albumSongs= value; }
    }
    //...
     
    //Constructeur
    public Album()
    {
    }
    public Album(int aId,string name)
    {
          this.ID=aId;      
          this.Name=name;
          GetSongs();      
    }
    public void GetSongs()
    {
          //Ici :
          //Requête qui ramène toutes les chansons de l'album dont l'id est : aId
          //Je mets le résultat de la requête dans une Hashtable lstSongs
          this.Songs = new System.Collections.Generic.List<Song>();
          Song song = new Song();
     
         for (int i=0;i<lstSongs.Count;i=i+2)
         {
               song.ID = lstSongs[i];
               song.Name = lstSongs[i +1];
               this.Songs.Add(song);
               song = new Song();
     
         }
    }
    Et je note ta remarque harz62 pour le foreach, c'est vrai que c'est une instruction que j'utilise peu...

    Merci à tous en tout cas !

  6. #6
    Membre émérite
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Par défaut
    Citation Envoyé par Giill Voir le message
    Et je note ta remarque harz62 pour le foreach, c'est vrai que c'est une instruction que j'utilise peu...
    Moi c'est les instructions for que je n'utilise jamais. L'avantage par rapport à un for c'est que l'on ne peut jamais avoir déclencher l'exception IndexoutOfRangeException.

  7. #7
    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 : 43
    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
    Par défaut
    Ce bout de code me surprend un peu...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
          Song song = new Song();
     
         for (int i=0;i<lstSongs.Count;i=i+2)
         {
               song.ID = lstSongs[i];
               song.Name = lstSongs[i +1];
               this.Songs.Add(song);
               song = new Song();
     
         }
    Evidemment, ça fonctionne, mais ce n'est pas très naturel... en plus en faisant comme ça tu instancies Song une fois de plus que nécessaire (la dernière instance n'est jamais utilisée). Il serait plus naturel, à mon avis, de faire comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
         for (int i=0;i<lstSongs.Count;i=i+2)
         {
               Song song = new Song();
               song.ID = lstSongs[i];
               song.Name = lstSongs[i +1];
               this.Songs.Add(song);
         }

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 49
    Par défaut
    Citation Envoyé par harz62 Voir le message
    Moi c'est les instructions for que je n'utilise jamais. L'avantage par rapport à un for c'est que l'on ne peut jamais avoir déclencher l'exception IndexoutOfRangeException.
    Effectivement, c'est un choix judicieux.
    Je me penche là-dessus demain.


    Citation Envoyé par tomlev
    Evidemment, ça fonctionne, mais ce n'est pas très naturel... en plus en faisant comme ça tu instancies Song une fois de plus que nécessaire (la dernière instance n'est jamais utilisée).
    C'est juste pour ta remarque sur l'instance supplémentaire de Song. En fait, je ne sais pas d'où je tiens ça, mais j'ai toujours cru que ce n'était pas une bonne pratique de déclarer une variable dans une boucle (Song song = new Song(); ).
    Du coup je la déclare avant la boucle, et l'instancie pour la première fois dans le même temps donc...Ce qui fait que pour ne pas l'instancier deux fois de suite, je choisis de le faire à la fin de la boucle, après le traitement.
    Mais comme tu le dis, ça ne change rien, puisqu'une instance "en trop" est créée.

    J'avoue ne pas savoir quelle est la bonne pratique dans ce cas, mais je suis ouvert à toute suggestion.

  9. #9
    Membre confirmé
    Inscrit en
    Avril 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 190
    Par défaut
    Citation Envoyé par harz62 Voir le message
    Moi c'est les instructions for que je n'utilise jamais. L'avantage par rapport à un for c'est que l'on ne peut jamais avoir déclencher l'exception IndexoutOfRangeException.
    l'avantage du for par rapport au foreach, c'est qu'on modifier une collection pendant qu'on la parcours !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Conception objet d'un Mario-like
    Par alex6891 dans le forum Développement 2D, 3D et Jeux
    Réponses: 26
    Dernier message: 14/10/2006, 09h09
  2. [2.0][OOP] conception objet
    Par CUCARACHA dans le forum Framework .NET
    Réponses: 8
    Dernier message: 12/10/2006, 09h27
  3. [Méthodes]Tuto conception objet
    Par Ethylene dans le forum Méthodes
    Réponses: 3
    Dernier message: 24/08/2006, 22h31
  4. [Perl Objet] Constructeur avec tableau en parametre
    Par crochepatte dans le forum Langage
    Réponses: 9
    Dernier message: 16/08/2006, 22h07
  5. [Conception] Objet User
    Par Invité dans le forum Général Java
    Réponses: 10
    Dernier message: 14/03/2006, 11h54

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