web-dev-qa-db-fra.com

Comment supprimer un élément pour une énumération de OR?

J'ai un enum comme:

public enum Blah
{
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16
}

Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;

Comment puis-je supprimer la couleur bleue des couleurs variables?

143
Blankman

Vous devez le & avec le ~ (complément) de 'BLUE'.

L’opérateur du complément inverse ou «renverse» tous les bits pour le type de données donné. En tant que tel, si vous utilisez l'opérateur AND (&) avec une valeur (appelons cette valeur 'X') et le complément d'un ou plusieurs bits de l'ensemble (appelons ces bits Q et leur complément ~Q), l'instruction X & ~Q efface tout bits qui ont été définis dans Q à partir de X et renvoie le résultat.

Donc, pour supprimer ou effacer les bits BLUE, utilisez l'instruction suivante:

colorsWithoutBlue = colors & ~Blah.BLUE
colors &= ~Blah.BLUE // This one removes the bit from 'colors' itself

Vous pouvez également spécifier plusieurs bits à effacer, comme suit:

colorsWithoutBlueOrRed = colors & ~(Blah.BLUE | Blah.RED)
colors &= ~(Blah.BLUE | Blah.RED) // This one removes both bits from 'colors' itself

ou alternativement ...

colorsWithoutBlueOrRed = colors & ~Blah.BLUE & ~Blah.RED
colors &= ~Blah.BLUE & ~Blah.RED // This one removes both bits from 'colors' itself

Donc, pour résumer:

  • X | Q définit le (s) bit (s) Q
  • X & ~Q efface bit (s) Q
  • ~X retourne/inverse tous les bits dans X
259
SLaks

Les autres réponses sont correctes, mais pour supprimer spécifiquement le bleu de ce qui précède, vous écririez:

colors &= ~Blah.BLUE;
40
par

And not it ...............................

Blah.RED | Blah.YELLOW == 
   (Blah.RED | Blah.BLUE | Blah.YELLOW) & ~Blah.BLUE;
8
Daniel A. White

Je pensais que cela pourrait être utile pour d'autres personnes qui ont trébuché ici comme moi. 

Faites attention à la manière dont vous gérez les valeurs d’énumération que vous pourriez définir avec une valeur == 0 (il peut parfois être utile d’avoir un état Inconnu ou Inactif pour une énumération). Cela pose des problèmes lors de l'utilisation de ces opérations de manipulation de bits.

De même, lorsque vous avez des valeurs énumérées combinant une autre puissance de 2 valeurs, par ex. 

public enum Colour
{
    None = 0,  // default value
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16,
    Orange = 18  // Combined value of RED and YELLOW
}

Dans ces cas, une méthode d'extension telle que celle-ci pourrait s'avérer utile:

public static Colour UnSet(this Colour states, Colour state)
{
    if ((int)states == 0)
        return states;

    if (states == state)
        return Colour.None;

    return states & ~state;
}

Et aussi la méthode équivalente IsSet qui gère les valeurs combinées (bien que de façon quelque peu hacky)

public static bool IsSet(this Colour states, Colour state)
{
    // By default if not OR'd
    if (states == state)
        return true;

    // Combined: One or more bits need to be set
    if( state == Colour.Orange )
        return 0 != (int)(states & state);

    // Non-combined: all bits need to be set
    return (states & state) == state;
}
7

Qu'en est-il de xor (^)?

Etant donné que le FLAG que vous essayez de supprimer est là, cela fonctionnera .. sinon, vous devrez utiliser un &.

public enum Colour
{
    None = 0,  // default value
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16,
    Orange = 18  // Combined value of RED and YELLOW
}

colors = (colors ^ Colour.RED) & colors;
2
user4509414

Pour simplifier l’énumération du drapeau et faire en sorte qu’il soit préférable de lire en évitant les multiples, nous pouvons utiliser le décalage de bits. (D'un bon article Fin du grand débat sur les drapeaux d'énum )

[FLAG]
Enum Blah
{
   RED = 1,
   BLUE = 1 << 1,
   GREEN = 1 << 2,
   YELLOW = 1 << 3
}

et aussi pour effacer tous les bits

private static void ClearAllBits()
{
    colors = colors & ~colors;
}
0
Matt Allen

Vous pouvez utiliser ceci:

colors &= ~Blah.RED; 
0
Majid gharaei