2 votes

Test pour les valeurs de drapeaux multiples

J'ai cette énumération de drapeaux :

public enum AssignmentType
{
    None = 0,
    Attendant = 1,
    ConductorCBS = 2,
    ReaderCBS = 4,
    Chairman = 8,
    Mike = 16,
    PlatformAttendant = 32,
    Prayer = 64,
    OCLM = 128,
    Sound = 256,
    Student = 512,
    Custom = 1024,
    Demonstration = 2048,
    Assistant = 4096
}

Je veux maintenant tester ma variable pour une certaine condition de drapeau.

Je veux identifier ma variable est seulement toute combinaison de :

  • None
  • Student
  • Assistant
  • Demonstration

Ainsi, si elle a l'une des autres valeurs de l'énumération, la variable ne satisfait pas au test.

Au début, j'ai commencé par ça :

bool bIsPersonnel = true;

if (_Assignments == AssignmentType.None ||
    _Assignments == AssignmentType.Demonstration || 
    _Assignments == AssignmentType.Student ||
    _Assignments == AssignmentType.Assistant ||
    _Assignments == (AssignmentType.Demonstration | AssignmentType.Student))
{
    bIsPersonnel = false;
}

Mais je me suis vite rendu compte de la multiplicité des choix possibles.

Existe-t-il un moyen plus simple ?

Je ne vois pas comment la réponse suggérée peut aider. Je pense que le plus simple est de faire mon test à l'envers. Il suffit de tester s'il a l'un des autres drapeaux alors je sais que c'est du personnel !

6voto

Jon Skeet Points 692016

Vous pouvez appliquer un masque avec la fonction ~ opérateur de négation par bit pour trouver tous les invalide et vérifier s'ils ont été appliqués.

var valid = AssignmentType.Student | AssignmentType.Assistant | AssignmentType.Demonstration;
var invalid = ~valid; // Everything that isn't valid

if ((_Assignments & invalid) != 0)
{
    // There was at least one invalid flag, handle it appropriately
}

Ou pour vérifier s'il est valide :

if ((_Assignment & invalid) == 0)
{
    // There are no invalid flags, handle it appropriately
}

Ou si vous ne cherchez qu'à définir un seul drapeau booléen, vous n'avez pas besoin d'un fichier de type if du tout :

bool isPersonnel = ((assignment & invalid) != 0);

2voto

Theodor Zoulias Points 1088

(Réponse incorrecte)

if ((_Assignments & AssignmentType.None) > 0
    || (_Assignments & AssignmentType.Student) > 0
    || (_Assignments & AssignmentType.Assistant) > 0
    || (_Assignments & AssignmentType.Demonstration) > 0
){
    bIsPersonnel = false;
}

Réponse corrigée :

var NonPersonnel = AssignmentType.None | AssignmentType.Student | AssignmentType.Assistant | Demonstration;
bool bIsPersonnel = (_Assignments | NonPersonnel) != NonPersonnel;

2voto

Enigmativity Points 26345

Je pense que cela fonctionne comme prévu :

var flags =
    AssignmentType.None
    | AssignmentType.Student
    | AssignmentType.Assistant
    | AssignmentType.Demonstration;

bool bIsPersonnel =
    !(_Assignments == AssignmentType.None
        || (flags & _Assignments) == _Assignments);

Voici quelques exemples de résultats :

_Assignments = AssignmentType.Demonstration | AssignmentType.Assistant; // False
_Assignments = AssignmentType.None; // False
_Assignments = AssignmentType.Demonstration | AssignmentType.Mike; // True

0voto

Andrew Truckle Points 4609

Pour l'instant, je suis arrivé à faire le test inverse :

bool bIsPersonnel = false;

if(_Assignments.HasFlag(AssignmentType.Attendant | AssignmentType.ConductorCBS |
    AssignmentType.ReaderCBS | AssignmentType.Chairman |
    AssignmentType.Mike | AssignmentType.PlatformAttendant |
    AssignmentType.Prayer | AssignmentType.OCLM |
    AssignmentType.Sound | AssignmentType.Custom))
{
    bIsPersonnel = true;
}

C'est plus facile car nous savons que si l'un de ces drapeaux est activé, la personne est "Personnel". Les autres drapeaux ne sont pas pris en compte et nous n'avons pas besoin de tester les configurations de drapeaux multiples.

0voto

Lưu Vĩnh Phúc Points 3183

Il suffit de créer un masque de valeurs à vérifier et and le masque avec la valeur, c'est ainsi que les drapeaux sont vérifiés, indépendamment du nombre de drapeaux.

if (0 != _Assignments &
     (AssignmentType.Demonstration | AssignmentType.Student | AssignmentType.Assistant))

Pas besoin de vérifier AssignmentType.None car ce n'est pas un drapeau lui-même, juste une valeur réservée égale à 0, utilisée pour vérifier qu'aucun drapeau n'est activé. Si la combinaison contient à la fois "aucun drapeau" et "un autre drapeau", cela n'a pas de sens, n'est-ce pas ? Si vous devez vérifier la condition "aucun drapeau", vérifiez-la séparément.

if (_Assignments == AssignmentType.None || (0 != _Assignments &
         (AssignmentType.Demonstration | AssignmentType.Student | AssignmentType.Assistant)))

C'est aussi comme ça que Enum.HasFlag() vérifie les drapeaux

public static void Main()
{
   DinnerItems myOrder = DinnerItems.Appetizer | DinnerItems.Entree |
                        DinnerItems.Beverage | DinnerItems.Dessert;
   DinnerItems flagValue = DinnerItems.Entree | DinnerItems.Beverage;
   Console.WriteLine("{0} includes {1}: {2}", 
                     myOrder, flagValue, myOrder.HasFlag(flagValue));
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X