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 :

Suggestion pour les flags en C#


Sujet :

C#

  1. #1
    Membre confirmé
    Homme Profil pro
    Activité
    Inscrit en
    Juillet 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Activité

    Informations forums :
    Inscription : Juillet 2005
    Messages : 94
    Par défaut Suggestion pour les flags en C#
    Bonjour,

    Lorsqu'on veut manipuler des flags, nous avons deux choix:

    Utiliser une énumération avec l'attribut [Flags] ou utiliser une structure.

    Avantages d'une énumération [Flags]:
    - Permet les comparaisons binaires.
    Désavantages d'une énumération [Flags]:
    - Opérations binaires nécessaires pour modifier un bit.

    Avantages d'une structure:
    - Modification d'un bit facile.
    Désavantages d'une structure:
    - Pas d'opérateurs binaires pour comparer la structure en entier.

    On pourrait envisager d'ajouter l'opérateur [] à un nombre de sorte que l'on puisse accéder à ses bits directement. Ainsi, nous aurions:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int i = 1024;
    i[9] = false;
    Nous pourrions donc déclarer une énumération allant de 0 à 31 permettant de manipuler jusqu'à 31 flags.

    Toutefois, nous nous retrouvons à devoir utiliser une énumération et un entier conjointement.

    Cette proposition reste une idée, mais inefficace pour les flags.

    La deuxième solution consisterait en une combinaison des forces de toutes ces idées:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public flags ErrorFlags{
        MessageCorrupted,
        SocketError,
        UnknownError,
    }
    C'est une déclaration semblable à une énumération. Toutefois, voici ce que flags nous permettrait:
    -Comparaisons binaires de l'ensemble complet.
    -Accès à un bit particulier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public void myFunc(){
        //Initialisation comme une énumération avec l'attribut [Flags]
        ErrorFlags myflags = ErrorFlags.MessageCorrupted | ErrorFlags.SocketError;
        //Comparaisons binaires de l'ensemble
        if(myflags == (ErrorFlags.MessageCorrupted & ErrorFlags.UnknownError)){
            //Accès à un bit particulier.
            myflags.UnknownError = false;
        }
     
    }
    Simple, élégant, que pensez-vous de cela?

    -Ajouter l'opérateur [] sur les int. (pas pour les flags mais pourraît être utile)
    -Créer l'équivalent de mon 'flags' dans l'exemple, qui ressemble à un enum ave c l'accès aux bits particuliers.

  2. #2
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Ben, c'est quoi la question


    Pis, dans ce que tu as écrit, pourquoi ne pas passer par une simple énumération ?

  3. #3
    Membre confirmé
    Homme Profil pro
    Activité
    Inscrit en
    Juillet 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Activité

    Informations forums :
    Inscription : Juillet 2005
    Messages : 94
    Par défaut
    L'énumération ne permet pas simplement de mettre un bit à off ou on, il faut avoir recours aux opérations binaires.

    Exemple

    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
     
    [Flags]
    public enum Errors{
        SocketError = 1,
        CorruptedMessage = 2,
        UnknownError = 4,
    }
     
    private void Exemple(){
        Errors myErrors = Errors.SocketError & Errors.UnknownError;
        //Mettre un bit à on.
        myErrors |= Errors.CorruptedMessage;
        //Inverser un bit.
        myErrors ^= Errors.CorruptedMessage;
        //Mettre un bit à off.
        myErrors &= !Errors.CorruptedMEssage;
    }
    Le processeur doit effectuer plusieurs opérations simplement pour modifier un bit. Il serait plus simple de l'accéder directement pour lui affecter sa valeur. Moins d'opérations seraient en jeu et le code tournerait plus vite:

    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
     
    public flags Errors{
        SocketError,
        CorruptedMessage,
        UnknownError,
    }
     
    private void Exemple(){
        Errors myErrors = Errors.SocketError & Errors.UnknownError;
        //Mettre un bit à on.
        myErrors |= Errors.CorruptedMessage;
        myErrors.CorruptedMessage = true;
        //Inverser un bit.
        myErrors ^= Errors.CorruptedMessage;
        myErrors.CorruptedMessage = !myErrors.CorruptedMessage;
        //Mettre un bit à off.
        myErrors &= !Errors.CorruptedMessage;
        myErrors.CorruptedMessage = false;
    }
    En passant, ce n'est pas une question, ce sont juste deux idées que j'ai eues et dont je souhaite discuter.

  4. #4
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Oui mais quel est l'intérêt ? Le langage est écrit comme ça, soit tu l'acceptes, soit tu utilises un autre langage.
    Je ne comprends pas ce que tu attends...
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  5. #5
    Membre confirmé
    Homme Profil pro
    Activité
    Inscrit en
    Juillet 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Activité

    Informations forums :
    Inscription : Juillet 2005
    Messages : 94
    Par défaut
    Je n'attends rien. Je ne compte pas modifier c# lol, mais peut-être envoyer la suggestion à Microsoft si après discussion, il s'avère que ça semble utile à plus d'une personne. Alors la question, c'est 'Comment trouvez-vous cette idée?' ou comme je l'ai dit vers la fin de mon premier message, 'Qu'en pensez-vous?'.

  6. #6
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    J'aime les enums comme elles sont
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  7. #7
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par SaumonAgile
    J'aime les enums comme elles sont
    +1: pkoi se compliquer la vie alors que ce que l'on a fonctionne très bien

  8. #8
    Membre confirmé
    Homme Profil pro
    Activité
    Inscrit en
    Juillet 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Activité

    Informations forums :
    Inscription : Juillet 2005
    Messages : 94
    Par défaut
    Et le progrès dans tout ça? Je vous rappelle que la programmation séquentielle fonctionne très bien. Ce n'est pas en se disant "pkoi se compliquer la vie alors que ce que l'on a fonctionne très bien" que notre situation a évoluée vers la POO.

    Oui les enums fonctionnent, et on peut travailler avec, moi je cherche des gens constructifs pour critiquer l'idée que j'ai lancée, pas pour me dire que ce que l'on a fonctionne.

    Au fait je viens d'apporter un correctif à ce que j'avais écrit, j'avais oublié les valeurs de mes enums qui ont l'attribut [Flags]: elles doivent être des puissances de deux. Autre chose qui serait inutile de faire avec 'flags' au lieu de 'enum'.

    Sois dit en passant, je ne propose pas un remplacement de enum par flags, mais un remplacement de '[Flags] enum' par 'flags', 'flags' étant un mot clé de C#.

  9. #9
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Ce n'est pas parce qu'on n'est pas d'accord qu'on n'est pas constructif.
    Personnellement je trouve ton idée d'accéder aux bits directement inutile et dangereuse.
    Pour une enum déclarée dans une assembly externe, tu aurais la possibilité de modifier des bits dans la valeur sans connaitre les valeurs définies. Au moins avec les enum classiques, en utilisant les opérations avec des bits tu utilises généralement le libellé de l'enum et pas des 1, 2, 4, etc.

    Le même problème se pose pour la maintenance, si tu commences à tomber sur du code où le développeur s'amuse à modifier directement les bits, tu es obligé d'aller dans la déclaration de l'enum pour trouver à quoi cela correspond... Bonjour le gain de temps et les parties de débogages endiablées...
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  10. #10
    Membre confirmé
    Homme Profil pro
    Activité
    Inscrit en
    Juillet 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Activité

    Informations forums :
    Inscription : Juillet 2005
    Messages : 94
    Par défaut
    Citation Envoyé par SaumonAgile
    Au moins avec les enum classiques, en utilisant les opérations avec des bits tu utilises généralement le libellé de l'enum et pas des 1, 2, 4, etc.
    Bon ça c'est ce que j'appelle un commentaire constructif. Je répondrais à cela en te disant de regarder davantage mon exemple plus haut.

    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
    public flags Errors{
        SocketError,
        CorruptedMessage,
        FatalError = SocketError | CorruptedMessage,
        UnknownError, 
    }   
     
    private void Exemple(){
        Errors myErrors = Errors.SocketError & Errors.UnknownError; 
     
        //Mettre un bit à on.  
        myErrors |= Errors.CorruptedMessage;
        myErrors.CorruptedMessage = true;
     
        //Inverser un bit.  
        myErrors ^= Errors.CorruptedMessage; 
        myErrors.CorruptedMessage = !myErrors.CorruptedMessage; 
     
        //Mettre un bit à off.  
        myErrors &= !Errors.CorruptedMessage;
        myErrors.CorruptedMessage = false;
     
        //Toutes les opérations peuvent aussi être effectuées sur des groupes de flags.
        myErrors.FatalError = false;
        myErrors.FatalError = true;
        myErrors.FatalError = !myErrors.FatalError;
    }
    Comme on le voit dans cet exemple d'utilisation, il n'y a pas un accès direct au bits et ce sont les libellés qui sont utilisés. Prenez l'exemple "myErrors.CorruptedMessage = false; ". Indirectement, tu as accès à un bit, ou s'il s'agit d'un ensemble de flags, tu as accès à un ensemble de flags comme une seule entité. L'idée, c'est de pouvoir affecter une valeur avoir à sortir les comparaisons binaires.

    Voilà un résumé de ce que ferait 'flags':
    1. Lors de la déclaration, les libellés ne peuvent pas être numérotés.
    2. Lors de la déclaration, un libellé peut être déclaré comme étant une combinaison d'autres libellés.
    3. Conservation des opérations binaires actuellement admises avec '[Flags] enum'.
    4. Possibilité d'accéder à un flag comme s'il s'agissait d'un membre de façon à lui affecter un booléen.

Discussions similaires

  1. Suggestion : Un favicon pour les forums dvp.net
    Par prgasp77 dans le forum Evolutions du club
    Réponses: 5
    Dernier message: 06/04/2005, 23h12

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