J'ai une énumération de drapeau ci-dessous.
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
Je ne peux pas donner à l'instruction if la valeur true.
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
if (testItem == FlagTest.Flag1)
{
// Do something,
// however This is never true.
}
Comment puis-je rendre cela vrai?
None
indicateur avec une valeur de zéro. Voir msdn.microsoft.com/en-us/library/vstudio/…&
opérateur à titre de comparaison,|
est comme une addition:1|2=3
,5|2=7
,3&2=2
,7&2=2
,8&2=0
.0
évalue àfalse
, tout le reste àtrue
.Réponses:
Dans .NET 4, il existe une nouvelle méthode Enum.HasFlag . Cela vous permet d'écrire:
ce qui est beaucoup plus lisible, IMO.
La source .NET indique que cela exécute la même logique que la réponse acceptée:
la source
Enum
classe.(testItem & FlagTest.Flag1)
est une opération AND au niveau du bit.FlagTest.Flag1
équivaut à001
l'énumération de OP. Maintenant, disonstestItem
a Flag1 et Flag2 (donc c'est au niveau du bit101
):la source
Pour ceux qui ont du mal à visualiser ce qui se passe avec la solution acceptée (qui est la suivante),
testItem
(selon la question) est défini comme,Ensuite, dans l'instruction if, le côté gauche de la comparaison est,
Et l'instruction if complète (qui prend la valeur true si
flag1
est définie danstestItem
),la source
@ phil-devaney
Notez que, sauf dans les cas les plus simples, Enum.HasFlag entraîne une forte pénalité de performances par rapport à l'écriture manuelle du code. Considérez le code suivant:
Plus de 10 millions d'itérations, la méthode d'extension HasFlags prend 4793 ms, contre 27 ms pour l'implémentation standard au niveau du bit.
la source
(«flag var» & «flag value») != 0
ne fonctionne pas pour moi. La condition échoue toujours et mon compilateur (Mono 2.6.5 d'Unity3D) signale un «avertissement CS0162: code inaccessible détecté» lorsqu'il est utilisé dans un fichierif (…)
.… = 1, … = 2, … = 4
sur les valeurs d'énumération est d'une importance critique lors de l'utilisation[Flags]
. Je supposais qu'il commencerait les entrées à1
et avancerait automatiquement par Po2s. Le comportement semble cohérent dans MS .NET et Mono daté de Unity. Mes excuses vous ont mis cela.J'ai mis en place une méthode d'extension pour le faire: question connexe .
Fondamentalement:
Ensuite, vous pouvez faire:
Incidemment, la convention que j'utilise pour les énumérations est au singulier pour le standard, au pluriel pour les drapeaux. De cette façon, vous savez à partir du nom enum s'il peut contenir plusieurs valeurs.
la source
HasFlag
extension à la place.Un conseil de plus ... Ne faites jamais la vérification binaire standard avec le drapeau dont la valeur est "0". Votre vérification sur ce drapeau sera toujours vraie.
Si vous vérifiez le paramètre d'entrée binaire par rapport à FullInfo - vous obtenez:
bPRez sera toujours vrai comme TOUT & 0 toujours == 0.
Au lieu de cela, vous devez simplement vérifier que la valeur de l'entrée est 0:
la source
la source
Pour les opérations sur les bits, vous devez utiliser des opérateurs de bits.
Cela devrait faire l'affaire:
Edit: Correction de mon if check - je suis retourné dans mes méthodes C / C ++ (merci à Ryan Farley pour l'avoir signalé)
la source
Concernant l'édition. Vous ne pouvez pas le rendre vrai. Je vous suggère d'envelopper ce que vous voulez dans une autre classe (ou méthode d'extension) pour vous rapprocher de la syntaxe dont vous avez besoin.
c'est à dire
la source
Essaye ça:
Fondamentalement, votre code demande si le fait d'avoir les deux indicateurs définis équivaut à avoir un indicateur défini, ce qui est évidemment faux. Le code ci-dessus ne laissera que le bit Flag1 défini s'il est défini, puis compare ce résultat à Flag1.la source
même sans [Flags], vous pouvez utiliser quelque chose comme ça
ou si vous avez une énumération de valeur zéro
la source