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 :

Définition de classes et leur utilisation avec des List [Débutant]


Sujet :

C#

  1. #1
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Décembre 2016
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Définition de classes et leur utilisation avec des List
    Bonjour à tous.

    Je suis en train d'apprendre le c# en autodidacte, je me suis fixé pour but d'arriver à écrire une application dans le genre du "snake" (le jeu).
    Je viens du delphi, je ne suis pas débutant en programmation, mais j'ai parfois du mal à mettre en code c# ce que je faisais en delphi, je bute sur des choses simples et je perds beaucoup de temps
    Et faire un copier-coller des nombreux codes du genre présents sur le net n'est pas très formateur ...

    Bref voila pour la courte présentation.

    Pour mon projet, j'ai défini 2 classes :
    - une qui contient la définition d'une coordonnée
    - une qui contient la définition du corps du serpent, en utilisant la classe coordonnée

    Ca nous donne donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    namespace Snake
    {
        class Coordonnee
        {
            public int X;
            public int Y;
        }
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    namespace Snake
    {
        class Serpent
        {
            public List<Coordonnee> CorpsSerpent = new List<Coordonnee>();
        }
    }
    Ensuite arrive le moment où je veux utiliser ces classes.

    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
    namespace Snake
    {
        public partial class Form1 : Form
        {
            Serpent UnSerpent = new Serpent(); // Création du serpent
            Coordonnee UneCoordonnee = new Coordonnee(); // Création d'une coordonnée
     
            public Form1()
            {
                InitializeComponent();
                CreerNouveauJeu(); // Initialisation d'un nouveau jeu
            }
            ...
            private void CreerNouveauJeu()
            {
                UnSerpent.CorpsSerpent.Clear(); // Nettoyage du corps du serpent
     
                UneCoordonnee.X = 16; // Initialisation coordonnée X
                UneCoordonnee.Y = 1; // Initialisation coordonnée Y
                UnSerpent.CorpsSerpent.Add(UneCoordonnee); // Ajout de ces coordonnées au corps du serpent
     
                UneCoordonnee.X = 1; // Initialisation coordonnée X
                UneCoordonnee.Y = 1; // Initialisation coordonnée Y
                UnSerpent.CorpsSerpent.Add(UneCoordonnee); // Ajout de ces coordonnées au corps du serpent
            }
        }
    }
    Les deux éléments de la liste sont bien crées, mais ils ne sont pas initialisés correctement.
    Le deuxième ajout de coordonnées semble écrasé les valeur du premier, le couple de valeur (x,y)=(16,1) disparait de la liste.

    C'est peut être une incompréhension sur le fonctionnement des List, ou une partie du code mal placé (j'ai du mal avec ça aussi), ou autre chose ...
    J'ai besoin d'aide.

  2. #2
    Membre chevronné
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    640
    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 : 640
    Points : 2 149
    Points
    2 149
    Par défaut
    Bonjour,

    ton problème vient de ce bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            private void CreerNouveauJeu()
            {
                UnSerpent.CorpsSerpent.Clear(); // Nettoyage du corps du serpent
     
                UneCoordonnee.X = 16; // Initialisation coordonnée X
                UneCoordonnee.Y = 1; // Initialisation coordonnée Y
                UnSerpent.CorpsSerpent.Add(UneCoordonnee); // Ajout de ces coordonnées au corps du serpent
     
                UneCoordonnee.X = 1; // Initialisation coordonnée X
                UneCoordonnee.Y = 1; // Initialisation coordonnée Y
                UnSerpent.CorpsSerpent.Add(UneCoordonnee); // Ajout de ces coordonnées au corps du serpent
            }
    Tu as défini Coordonnee comme une classe, et tu rajoutes toujours le même objet de cette classe. Du coup, si tu modifies les propriétés de cet objet, tout changera, car ta liste pour l'instant n'est rempli que du même et seul objet.

    Pour y remédier, soit tu créer un nouvel objet de type Coordonnee pour autant de coordonnées. Soit tu passes Coordonee en structure. C'est selon tes besoins.

    Si tu as des difficultés sur ce point, je te conseille de chercher la différence entre passage de valeur et passage de réference.

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par PixelJuice Voir le message
    Tu as défini Coordonnee comme une classe, et tu rajoutes toujours le même objet de cette classe. Du coup, si tu modifies les propriétés de cet objet, tout changera, car ta liste pour l'instant n'est rempli que du même et seul objet.

    Pour y remédier, soit tu créer un nouvel objet de type Coordonnee pour autant de coordonnées. Soit tu passes Coordonee en structure. C'est selon tes besoins.
    Je dirais même que plutôt de passer par une (ou plusieurs) instance locale, il me semble préférable d'utiliser directement l'élément dans la liste.

    1/ En créant un constructeur adéquat à la classe "Coordonnee" :
    Code csharp : 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
     
    namespace Snake
    {
        class Coordonnee
        {
            public int X { get; private set; }
            public int Y { get; private set; }
     
            public Coordonnee(int x, int y)
            {
                 X = x;
                 Y = y;
            }
        }
        ...
        public partial class Form1 : Form
        {
            private void CreerNouveauJeu()
            {
                UnSerpent.CorpsSerpent.Clear(); // Nettoyage du corps du serpent
     
                UnSerpent.CorpsSerpent.Add(new UneCoordonnee(16, 1)); // Ajout de ces coordonnées au corps du serpent
                UnSerpent.CorpsSerpent.Add(new UneCoordonnee(1, 1)); // Ajout de ces coordonnées au corps du serpent
            }
        }
    }

    2/ En utilisant un constructeur dynamique (plus moderne, mais moins lisible, je trouve)
    Code csharp : 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
     
    namespace Snake
    {
        class Coordonnee
        {
            public int X { get; private set; }
            public int Y { get; private set; }
        }
        ...
        public partial class Form1 : Form
        {
            private void CreerNouveauJeu()
            {
                UnSerpent.CorpsSerpent.Clear(); // Nettoyage du corps du serpent
     
                UnSerpent.CorpsSerpent.Add(new UneCoordonnee() { X = 16, Y = 1 }); // Ajout de ces coordonnées au corps du serpent
                UnSerpent.CorpsSerpent.Add(new UneCoordonnee() { X = 1, Y = 1 }); // Ajout de ces coordonnées au corps du serpent
            }
        }
    }

    2 bis/ En utilisant un constructeur dynamique (plus moderne, mais moins lisible, je trouve)
    Code csharp : 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
     
    namespace Snake
    {
        class Coordonnee
        {
            public int X { get; private set; }
            public int Y { get; private set; }
        }
        ...
        public partial class Form1 : Form
        {
            private void CreerNouveauJeu()
            {
                UnSerpent.CorpsSerpent.Clear(); // Nettoyage du corps du serpent
     
                UnSerpent.CorpsSerpent.AddRange(new Coordonnee[] { new Coordonnee() { X = 16, Y = 1 }, new Coordonnee() { X = 1, Y = 1 } }); // Ajout de ces coordonnées au corps du serpent
            }
        }
    }

    3/ En modifiant directement les propriétés des instances dans la liste (mais ça peut vite être le bordel) :
    Code csharp : 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
     
    namespace Snake
    {
        class Coordonnee
        {
            public int X { get; set; }
            public int Y { get; set; }
        }
        ...
        public partial class Form1 : Form
        {
            private void CreerNouveauJeu()
            {
                UnSerpent.CorpsSerpent.Clear(); // Nettoyage du corps du serpent
     
                UnSerpent.CorpsSerpent.Add(new UneCoordonnee()); // Ajout de ces coordonnées au corps du serpent
                UnSerpent.CorpsSerpent.Add(new UneCoordonnee()); // Ajout de ces coordonnées au corps du serpent
                UnSerpent.CorpsSerpent[0].X = 16;
                UnSerpent.CorpsSerpent[0].Y = 1;
                UnSerpent.CorpsSerpent[1].X = 1;
                UnSerpent.CorpsSerpent[1].Y = 1;
            }
        }
    }
    On ne jouit bien que de ce qu’on partage.

  4. #4
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Décembre 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Décembre 2016
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Merci de vos réponses

    @ StringBuilder
    J'ai utilisé la solution 2, ça marche effectivement bien mieux comme ça

    @ PixelJuice
    J'ai encore un peu de mal avec cette notion d'objet, je vais me renseigner sur les passages de valeur et références

    J'ai bien avancé du coup !

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    l'objet c'est la base oui
    en fait quand tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var c = new Coordonnee();
    new Coordonnee est exécuté en premier, ca créé un espace mémoire pour recevoir l'instance de cette classe (qui contient x et y, qui étant des int font 4 octets)
    puis l'adresse mémoire de cette instance est placée dans c
    si tu fais ensuite
    alors un nouvel espace mémoire est créé, et c pointe maintenant vers cette instance mémoire

    l'ancienne instance mémoire n'est ici plus pointée par personne, elle sera supprimée de la mémoire (mais ce n'est pas le sujet ici ^^)

    si tu fais
    d est un pointeur, qui va pointer vers la même instance que c ; ce n'est pas l'objet qui est dupliqué mais la référence vers celui ci
    donc modifier d.x "modifie" indirectement c.x
    il n'y a pas réellement de modification de c, c'est que vu que c'est la même instance ca va lire le même espace mémoire, donc ca reflète le changement
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    2/ En utilisant un constructeur dynamique (plus moderne, mais moins lisible, je trouve)
    Code csharp : 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
     
    namespace Snake
    {
        class Coordonnee
        {
            public int X { get; private set; }
            public int Y { get; private set; }
        }
        ...
        public partial class Form1 : Form
        {
            private void CreerNouveauJeu()
            {
                UnSerpent.CorpsSerpent.Clear(); // Nettoyage du corps du serpent
     
                UnSerpent.CorpsSerpent.Add(new UneCoordonnee() { X = 16, Y = 1 }); // Ajout de ces coordonnées au corps du serpent
                UnSerpent.CorpsSerpent.Add(new UneCoordonnee() { X = 1, Y = 1 }); // Ajout de ces coordonnées au corps du serpent
            }
        }
    }
    À partir de quelle version du langage c'est possible avec des setters en private ?

  7. #7
    Max
    Max est déconnecté
    Expert éminent sénior

    Avatar de Max
    Homme Profil pro
    Artisan développeur
    Inscrit en
    Mai 2007
    Messages
    2 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Artisan développeur
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2007
    Messages : 2 954
    Points : 14 979
    Points
    14 979
    Par défaut
    Citation Envoyé par Noxen Voir le message
    À partir de quelle version du langage c'est possible avec des setters en private ?
    C# 2 il me semble

  8. #8
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Citation Envoyé par Max Voir le message
    C# 2 il me semble
    Cette syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var c = new UneCoordonnee() { X = 16, Y = 1 }
    existe depuis C# 3 pour être plus précis, mais elle implique des setters publics puisqu'elle est équivalente à celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var c = new UneCoordonnee();
    c.X = 16;
    c.Y = 1;
    C'est toujours comme ça en C# 6. Je me disais qu'une version ultérieure pourrait éventuellement devenir plus permissive sur l'accessibilité du setter dans son usage au sein d'un initialiseur, néanmoins ce serait quand-même une atteinte au principe d'encapsulation.

  9. #9
    Max
    Max est déconnecté
    Expert éminent sénior

    Avatar de Max
    Homme Profil pro
    Artisan développeur
    Inscrit en
    Mai 2007
    Messages
    2 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Artisan développeur
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2007
    Messages : 2 954
    Points : 14 979
    Points
    14 979
    Par défaut
    Citation Envoyé par Noxen Voir le message
    Cette syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var c = new UneCoordonnee() { X = 16, Y = 1 }
    existe depuis C# 3 pour être plus précis, mais elle implique des setters publics puisqu'elle est équivalente à celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var c = new UneCoordonnee();
    c.X = 16;
    c.Y = 1;
    C'est toujours comme ça en C# 6. Je me disais qu'une version ultérieure pourrait éventuellement devenir plus permissive sur l'accessibilité du setter dans son usage au sein d'un initialiseur, néanmoins ce serait quand-même une atteinte au principe d'encapsulation.
    Oula j'ai mal compris ta question et donc ai répondu à côté de la plaque

  10. #10
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Citation Envoyé par Max Voir le message
    Oula j'ai mal compris ta question et donc ai répondu à côté de la plaque
    C'est ce que j'avais déduit, j'ai donc précisé ma pensée :-)

  11. #11
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Oups, désolé, tapé mon code trop vite
    On ne jouit bien que de ce qu’on partage.

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

Discussions similaires

  1. Classes PyQt et doublons avec des modules Python
    Par Neitsa dans le forum PyQt
    Réponses: 4
    Dernier message: 20/09/2011, 12h24
  2. Sprite manager : utilisation avec des classes derivées de Sprite
    Par TheDrev dans le forum Développement 2D, 3D et Jeux
    Réponses: 10
    Dernier message: 14/05/2008, 21h53
  3. Réponses: 2
    Dernier message: 14/12/2007, 01h47
  4. Utilisation avec des cartes d'acquisition
    Par engineer_23 dans le forum OpenCV
    Réponses: 0
    Dernier message: 26/07/2007, 12h17
  5. [JpGraph] Utilisation avec des sessions
    Par dervish dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 29/01/2007, 11h11

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