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 :

Intégration de paquets d'énumérateurs dans une classe


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur indépendant de jeux
    Inscrit en
    Septembre 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur indépendant de jeux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2017
    Messages : 22
    Par défaut Intégration de paquets d'énumérateurs dans une classe
    Bonjour,

    Je suis à la recherche d'une fonctionnalité un peu spécifique qui nécessite que j'explique brièvement l'architecture de mon programme. Tout est ci-dessous, et mes deux questions sont à la fin.

    SITUATION
    Je suis en train de créer un jeu vidéo sur Unity en C#

    ENUMERATEURS
    J'utilise des énumérateurs comme des constantes afin de rendre mon code plus lisible. Il y a par exemple des fonctions qui demandent un paramètre entier (qui peut correspondre au numéro d'un objet à instancier, ou au mode de fonctionnement de cet objet), et j'utilise les énumérateurs dans ces situations, afin que mon code soit absolument lisible, et aussi pour ne pas m'emmêler les pinceaux au fur et à mesure que mes énumérateurs s'enrichissent.
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    InstancierAnimal((int)INSECTE.CHENILLE); // Instancier l'objet dont le numéro correspond à "INSECTE.CHENILLE"
    ChangerMode((int)COMPORTEMENT.PASSIF); // Attribuer (à l'animal) le comportement dont le numéro correspond à "COMPORTEMENT.PASSIF"
    ExecuterMeteo((int)METEO.PLUIE); // Exécuter la condition météorologique dont le numéro correspond à "METEO.PLUIE"
    HIERARCHIE
    Etant donné que les énumérateurs sont utilisés un peu partout dans l'ensemble de mes classes, il existe une classe mère dont presque toutes les autres héritent : "CODENAMES", et celle-ci contient principalement les énumérateurs (ainsi qu'une poignée de méthodes qu'il est utile d'implémenter aussi haut dans la hiérarchie).

    SOUCI
    Mon "souci" c'est que j'ai maintenant écrit plusieurs dizaines d'énumérateurs différents et qu'il y a tout un tas de classes qui n'en utilisent que deux ou trois. Je ne peux pas vraiment "descendre" les énumérateurs dans la hiérarchie, mais la plupart sont inutiles. Par exemple, l'énumérateur "METEO" est accessible par la classe "Animal", mais ça ne lui sert jamais à rien.

    PROPOSITION
    Mon idée, dont je ne sais pas encore comment elle peut être réalisée, consisterait à créer des "paquets" d'énumérateurs qui pourraient être intégrés à discrétion dans les différentes classes.
    Par exemple, la classe "Animal" importerait un paquet d'énumérateurs qui contiendrait "INSECTE" et "COMPORTEMENT", mais pas "METEO"
    Autre piste : on pourrait utiliser le mot-clé "using", comme quand on intègre des bibliothèques dans les classes.

    QUESTIONS
    - Pensez-vous que cela soit tout simplement utile? Est-ce que mon code est suscepible d'être plus performant ainsi? En d'autres termes, est-ce utile de ne pas intégrer des centaines de constantes inutilisées dans chaque classe?
    - Comment procéderiez-vous pour créer et intégrer les "paquets d'enumérateurs" tels que je les envisage?

    Merci d'avance pour vos conseils!

  2. #2
    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
    Tout d'abord, même si ça ne change rien au sujet, il y a une confusion sur les termes.

    Un énumérateur est un objet permettant le parcours d'une collection avec un foreach.
    https://learn.microsoft.com/fr-fr/do...r?view=net-7.0

    Une énumération est un type qui déclare un ensemble de constantes nommées, mais qui du coup n'a pas de méthodes.
    https://learn.microsoft.com/fr-fr/do...fication/enums

    Puisque tu as besoin d'avoir des constantes et des méthodes tu peux créer des classes avec des propriété statiques :
    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
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Insecte.Chenille);
            Console.Read();
        }
    }
     
    public class Insecte
    {
        public static int Chenille { get => 0; }
        public static int Mouche { get => 1; }
     
        public void Methode()
        {
     
        }
     
    }
    Mais sans avoir une idée de ce que fait ton code, il est difficile de mieux t'orienter.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur indépendant de jeux
    Inscrit en
    Septembre 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur indépendant de jeux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2017
    Messages : 22
    Par défaut
    Citation Envoyé par popo Voir le message
    Tout d'abord, même si ça ne change rien au sujet, il y a une confusion sur les termes.
    [...]
    Puisque tu as besoin d'avoir des constantes et des méthodes tu peux créer des classes avec des propriété statiques :
    [...]
    Mais sans avoir une idée de ce que fait ton code, il est difficile de mieux t'orienter.
    Bonjour, merci pour la précision.
    Chez moi il s'agit bien d'énumérations.

    Par contre je n'ai pas besoin de méthodes. J'ai juste besoin de constantes. Mais mon intention, c'est de les intégrer aux différentes classes par un autre moyen que l'héritage.

    Concernant le code, j'aimerais bien pouvoir montrer un peu plus de détails, mais à moins de vous transmettre tout le projet (plusieurs dizaines de classes) je ne vois pas comment je peux être plus exhaustif.
    Pour schématiser, mon souci c'est principalement qu'il y a des dizaines d'énumérations dans la classe 1 ("CODENAMES", dont héritent toutes les autres), mais que chaque classe n'en utilise qu'une poignée. Par exemple, l'énumération "INSECTE" est utilisée dans les classes 1.1.1 et 1.1.2, et 1.2.1, ce qui m'oblige à les déclarer dans la classe 1 (avec comme conséquence que toutes les classes qui héritent de 1 "ont connaissance" de cet énumération, mais aucune utilisation n'en est jamais faite). Idealement, je cherche une solution qui me permettrait de déclarer les énumérations dans un objet (une classe?) à part, et ajouter une instruction pour l'intégrer dans les classes qui en ont besoin, indépendamment de la hiérarchie.

  4. #4
    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
    Citation Envoyé par SUISUgames Voir le message
    Pour schématiser, mon souci c'est principalement qu'il y a des dizaines d'énumérations dans la classe 1 ("CODENAMES", dont héritent toutes les autres), mais que chaque classe n'en utilise qu'une poignée. Par exemple, l'énumération "INSECTE" est utilisée dans les classes 1.1.1 et 1.1.2, et 1.2.1
    Pourquoi utiliser des nombre au lieu de vrai nom de classe ?
    CODENAMES est plus concret que "Classe 1"...

    Citation Envoyé par SUISUgames Voir le message
    Par exemple, l'énumération "INSECTE" est utilisée dans les classes 1.1.1 et 1.1.2, et 1.2.1, ce qui m'oblige à les déclarer dans la classe 1 (avec comme conséquence que toutes les classes qui héritent de 1 "ont connaissance" de cet énumération, mais aucune utilisation n'en est jamais faite).
    Faux, il suffit de déclarer ton énumération dans les classes 1.1.1 et 1.1.2, et 1.2.1.

  5. #5
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Attention aux termes ! Comme le souligne fort bien popo, il ne s'agit pas d'énumérateur, mais d'énumération !

    J'entrevois un peu une solution "usine à gaz" pour ce cas là, qui va mélanger interface et méthode d'extension. Exemple rapide :
    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
     
    public enum InsecteEnum
    {
       Chenille,
       Cafard,
       Fourmi
    }
     
    // Classe qui permet de récupérer les valeurs de l'énumération depuis une instance
    public class InsecteClass
    {
       public static _instance = new InsecteClass();
       public static InsecteClass Intance => _instance;
     
       public InsecteEnum Chenille => InsecteEnum.Chenille;
       public InsecteEnum Cafard => InsecteEnum.Cafard;
       public InsecteEnum Fourmi => InsecteEnum.Fourmi;
    }
     
    // Juste pour la forme, elle ne fait rien
    public interface IInsecte
    { }
     
    public static class IInsecteExtension
    {
       public static InsecteClass Insecte(this IInsecte insecte) { return InsecteClass.Instance; }
    }
     
    public class Animal : IInsecte
    {
       public void MaMethode()
       {
          InstancierAnimal(this.Insecte().Fourmi);
       }
    }
    C'est un peu moche à plusieurs titre :
    • cela transforme des accès à une énumération ou à une constante en appel à une méthode
    • on part de this alors qu'en théorie, c'est totalement inutile



    ---- 2e méthode ----
    Pendant l'écriture de cette première méthode, il m'est venu à l'esprit une seconde méthode, plus propre, que voici :
    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
     
    public enum InsecteEnum
    {
       Chenille,
       Cafard,
       Fourmi
    }
     
    // Classe qui permet de récupérer les valeurs de l'énumération depuis une instance
    public class InsecteClass
    {
       public static _instance = new InsecteClass();
       public static InsecteClass Intance => _instance;
     
       public InsecteEnum Chenille => InsecteEnum.Chenille;
       public InsecteEnum Cafard => InsecteEnum.Cafard;
       public InsecteEnum Fourmi => InsecteEnum.Fourmi;
    }
     
    public class Animal
    {
       private static InsecteClass Insecte = InsecteClass.Instance;
       private static ComportementClass Comportement = ComportementClass.Instance;
       // Pas besoin de la météo, donc inutile d'y ajouter une variable de class
     
     
       public void MaMethode()
       {
          InstancierAnimal(Insecte.Fourmi);
          // InstancierAnimal(this.Insecte.Fourmi); fonctionne aussi, mais le mot-clé this est facultatif ici
       }
     
    }
    Cette 2e approche à l'avantage de ne pas souffrir des inconvénients de la première.

    Fun fact, en jouant sur la visibilité private/protected de l'instance static Insecte, on peut décider si cette dernière doit être visible dans les classes dérivées ou non.

    A noter aussi que la classe InsecteClass peut se charger de convertir en entier tes énumérations si besoin est, dégageant au passage le besoin de cast.

Discussions similaires

  1. Intégration d'un appel setInterval dans une classe
    Par alexis_c dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 20/07/2022, 09h48
  2. [Toutes versions] Soucis d'intégration dans une classe controls (memoire insuffisante)
    Par patricktoulon dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 21/08/2015, 17h55
  3. Réponses: 8
    Dernier message: 09/07/2005, 23h10
  4. Thread dans une classe ?
    Par Sephi dans le forum Threads & Processus
    Réponses: 7
    Dernier message: 07/03/2004, 18h16
  5. Fonction callback dans une classe
    Par julian_ross dans le forum MFC
    Réponses: 8
    Dernier message: 02/03/2004, 11h42

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