2009-02-24 3 views
3

J'ai deux drapeaux:Enum comme drapeau à l'aide, le réglage et décalage

[Flags] 
enum Flags 
{ 
    A = 1, 
    B = 2 
}; 

Je les mets comme ceci:

Mode = Flags.A | Flags.B; // default value 
for(int i = 0; i < args.Length; i++) { 
switch(args[i]) 
{ 
    case "--a": 
    { 
    if ((Mode & Flags.A) == Flags.A && (Mode & Flags.B) == Flags.B) 
    // both, default assume 
    { 
     Mode = Flags.A; // only A 
    } 
    else 
    { 
     Mode |= Flags.A; // append A 
    } 
    break; 
    } 
    case "--b": 
    { 
    if ((Mode & Flags.A) == Flags.A && (Mode & Flags.B) == Mode.B) 
    { 
     Mode = Flags.B; 
    } 
    else 
    { 
     Mode |= Flags.B; 
    } 
    break; 
    } 
} } 

et les utiliser par la suite comme ceci:

if((Mode & Flags.A) == Flags.A) 
{ 
// 
} 
if((Mode & Flags.B) == Flags.B) 
{ 
// 
} 

Réserve majeure: Les deux drapeaux peuvent être définis. Ou juste un, dans ce cas, une seule partie du code est exécutée.

Est-ce que mon code est bon? Quelle est la meilleure façon de configurer les drapeaux?

Mise à jour: Est-ce moins moche que d'abord, comment pensez-vous?

Mode = 0; // default value now is empty 
for(int i = 0; i < args.Length; i++) { 
switch(args[i]) 
{ 
    case "--a": 
    { 
    Mode |= Flags.A; 
    break; 
    } 
    case "--b": 
    { 
    Mode |= Flags.B; 
    break; 
    } 
} } 
if(Mode == 0) 
{ 
    Mode = Flags.A | Flags.B; // if no parameters are given, setup both flags 
} 
+0

Votre code est syntaxiquement correct mais il est difficile de dire si c'est "bon" sans comprendre votre problème un peu plus. Votre question est un peu vague et vos commentaires sur les réponses le font plus. Pouvez-vous donner un peu plus? À première vue, votre solution est trop complexe pour le problème tel que présenté. – Simon

+0

Salut. Il y a la valeur par défaut A | B. Si le paramètre -a est donné en mode de réglage uniquement à A, si -b seulement à B, et si les deux sont donnés à (par défaut) A | B. Quelle est la meilleure façon de vérifier que la valeur actuelle est la valeur par défaut (A | B) pour la changer en A ou B si nécessaire. – abatishchev

Répondre

8

Voilà comment je mettrais mes drapeaux:

Mode = 0; 
for(int i = 0; i < args.Length; i++) { 
    switch(args[i]) { 
    case "--a": 
     Mode |= Flags.A; 
     break; 
    case "--b": 
     Mode |= Flags.B; 
     break; 
    } 
} 

Si les deux drapeaux doivent être par défaut, je pense qu'il est plus logique de modifier les paramètres de ligne de commande à quelque chose comme --not-a et --not-b. Cela reflète à la fois le paramètre par défaut, et vous permet de vous débarrasser de (Mode & Flags.A) == Flags.A && (Mode & Flags.B) == Flags.B, ce qui est plutôt laid, à mon humble avis.

Ensuite, vous pouvez définir vos drapeaux comme ceci:

Mode = Flags.A | Flags.B; 
for(int i = 0; i < args.Length; i++) { 
    switch(args[i]) { 
    case "--not-a": 
     Mode &= ~Flags.A; 
     break; 
    case "--not-b": 
     Mode &= ~Flags.B; 
     break; 
    } 
} 

Enfin, si vous avez beaucoup de drapeaux (au lieu de deux), il pourrait être plus facile de configurer votre ENUM comme ceci:

[Flags] 
enum Flags 
{ 
    A = 1, 
    B = 1 << 1, 
    C = 1 << 2, 
    D = 1 << 3, 
    E = 1 << 4, 
    F = 1 << 5 
}; 
+0

Remarque principale est à propos de la valeur par défaut est A | B. Donc, ajouter juste en utilisant | = ne suffit pas. – abatishchev

+0

J'ai mis à jour ma réponse. –

+0

Je suis d'accord sur la laideur de ce code, regardez s'il vous plaît au poste principal, qu'en pensez-vous? – abatishchev

2

Vous pouvez transformer un "peu" off avec la merveilleuse déclaration suivante:

Mode &= ~Flags.A; 

Je aurait déconseillons fortement inclu ding une valeur « null » dans votre ENUM ainsi:

[Flags] 
enum Flags 
{ 
    Null = 0; 
    A = 1, 
    B = 2; 
} 

Il gardera votre vie plus simple! :-)

+0

Merci, je vais regarder & = ~! Mais ne suis pas d'accord avec vous pour avoir un drapeau nul. MSDN recommande de ne pas! http://msdn.microsoft.com/en-us/library/ms229062.aspx "Il n'existe aucun moyen de vérifier qu'un indicateur de valeur zéro est explicitement défini, par opposition à aucun indicateur défini." – abatishchev

+0

Ce n'est pas pour régler un bit individuel. C'est pour effacer et donner une valeur par défaut définie. Et il est plus facile de tester si un bit est défini en tapant if ((Mode & Flags.A)! = Flags.Null.) Il y a beaucoup de raisons pour lesquelles la vie sera plus simple avec une valeur .Null. un! –

+0

Je suis d'accord avec avoir une valeur nulle pour une énumération de style drapeaux, mais Microsoft recommande le nom Aucun, pas Null - comme mentionné dans le document @abatishchev liens vers. – RenniePet

1

La deuxième version est beaucoup mieux - c'est exactement ce que je ferais. Remplacez Mode == null par Mode == 0 cependant.

Mode = 0; // default value now is empty 
for(int i = 0; i < args.Length; i++) { 
    switch(args[i]) 
    { 
     case "--a": 
      Mode |= Flags.A; 
      break; 

     case "--b": 
      Mode |= Flags.B; 
      break; 
    } 
} 

if(Mode == 0) 
{ 
    Mode = Flags.A | Flags.B; // if no parameters are given, setup both flags 
} 
Questions connexes