Si j'ai une variable contenant une énumération d'indicateurs, puis-je en quelque sorte itérer sur les valeurs de bits dans cette variable spécifique? Ou dois-je utiliser Enum.GetValues pour parcourir l'ensemble de l'énumération et vérifier lesquels sont définis?
c#
enums
enum-flags
Olivier Rogier
la source
la source
Réponses:
la source
HasFlag
est disponible à partir de .NET 4.Enum.GetValues(input.GetType()).Cast<Enum>().Where(input.HasFlag);
Ensuite, juste:myEnum.GetFLags()
:)static IEnumerable<Enum> GetFlags(this Enum input)
Voici une solution Linq au problème.
la source
.Where(v => !Equals((int)(object)v, 0) && e.HasFlag(v));
si vous avez une valeur nulle à représenterNone
Il n'y a pas de méthodes intégrées pour obtenir chaque composant pour autant que je sache. Mais voici une façon de les obtenir:
J'ai adapté ce qui
Enum
fait en interne pour générer la chaîne pour renvoyer à la place les drapeaux. Vous pouvez regarder le code dans le réflecteur et devrait être plus ou moins équivalent. Fonctionne bien pour les cas d'utilisation généraux où il existe des valeurs contenant plusieurs bits.La méthode d'extension
GetIndividualFlags()
obtient tous les indicateurs individuels pour un type. Les valeurs contenant plusieurs bits sont donc omises.la source
Bar
,Baz
etBoo
au lieu de justeBoo
.Boo
(la valeur renvoyée avecToString()
). Je l'ai modifié pour n'autoriser que les indicateurs individuels. Donc, dans mon exemple, vous pouvez obtenirBar
etBaz
au lieu deBoo
.Pour en revenir quelques années plus tard, avec un peu plus d'expérience, ma réponse ultime pour les valeurs à un seul bit, passant du bit le plus bas au bit le plus élevé, est une légère variante de la routine interne de Jeff Mercado:
Cela semble fonctionner, et malgré mes objections d'il y a quelques années, j'utilise HasFlag ici, car c'est beaucoup plus lisible que d'utiliser des comparaisons au niveau du bit et la différence de vitesse est insignifiante pour tout ce que je vais faire. (Il est tout à fait possible qu'ils aient amélioré la vitesse de HasFlags depuis de toute façon, pour tout ce que je sais ... je n'ai pas testé.)
la source
yield return bits;
?En partant de la méthode de @ Greg, mais en ajoutant une nouvelle fonctionnalité à partir de C # 7.3, la
Enum
contrainte:La nouvelle contrainte permet à cela d'être une méthode d'extension, sans avoir à effectuer de conversion
(int)(object)e
, et je peux utiliser laHasFlag
méthode et convertir directement àT
partir devalue
.C # 7.3 a également ajouté des contraintes pour les délicats et
unmanaged
.la source
flags
paramètre soit également de type génériqueT
, sinon vous devrez spécifier explicitement le type enum chaque fois que vous l'appelez.+1 pour la réponse fournie par @ RobinHood70. J'ai trouvé qu'une version générique de la méthode me convenait.
EDIT Et +1 pour @AustinWBryan pour avoir introduit C # 7.3 dans l'espace de solution.
la source
Vous n'avez pas besoin d'itérer toutes les valeurs. vérifiez simplement vos drapeaux spécifiques comme ceci:
ou (comme pstrjds l'a dit dans les commentaires), vous pouvez vérifier son utilisation comme:
la source
Ce que j'ai fait, c'est changer mon approche, au lieu de taper le paramètre d'entrée de la méthode comme
enum
type, je l'ai tapé comme un tableau duenum
type (MyEnum[] myEnums
), de cette façon, je viens de parcourir le tableau avec une instruction switch à l'intérieur de la boucle.la source
N'était pas satisfait des réponses ci-dessus, même si elles étaient le début.
Après avoir rassemblé quelques sources différentes ici:
Affiche précédente dans le projet de code SO QnA de ce fil
Enum Flags Check Post
Great Enum <T> Utility
J'ai créé ceci alors laissez-moi savoir ce que vous en pensez.
Paramètres:: lui
bool checkZero
dit d'autoriser0
comme valeur d'indicateur. Par défaut,input = 0
retourne vide.bool checkFlags
: lui dit de vérifier si leEnum
est décoré avec l'[Flags]
attribut.PS. Je n'ai pas le temps pour le moment de comprendre l'
checkCombinators = false
alg qui le forcera à ignorer les valeurs d'énumération qui sont des combinaisons de bits.Cela utilise la classe Helper Enum <T> trouvée ici que j'ai mise à jour
yield return
pourGetValues
:Enfin, voici un exemple d'utilisation:
la source
En s'appuyant sur la réponse de Greg ci-dessus, cela prend également en charge le cas où vous avez une valeur 0 dans votre énumération, telle que None = 0. Dans ce cas, il ne devrait pas itérer sur cette valeur.
Quelqu'un saurait-il comment améliorer encore davantage cela afin qu'il puisse gérer le cas où tous les indicateurs de l'énumération sont définis d'une manière super intelligente qui pourrait gérer tous les types enum sous-jacents et le cas de All = ~ 0 et All = EnumValue1 | EnumValue2 | EnumValue3 | ...
la source
Vous pouvez utiliser un itérateur de Enum. À partir du code MSDN:
Ce n'est pas testé, donc si j'ai fait une erreur, n'hésitez pas à m'appeler. (évidemment ce n'est pas rentrant.) Vous devrez attribuer une valeur au préalable, ou la décomposer dans une autre fonction qui utilise enum.dayflag et enum.days. Vous pourrez peut-être aller quelque part avec le contour.
la source
Cela pourrait être ainsi que le code suivant:
Il entre à l'intérieur si ce n'est que lorsque la valeur enum est contenue dans la valeur
la source
Toutes les réponses fonctionnent bien avec des indicateurs simples, vous allez probablement avoir des problèmes lorsque les indicateurs sont combinés.
probablement besoin d'ajouter une vérification pour tester si la valeur enum elle-même est une combinaison. Vous auriez probablement besoin de quelque chose comme publié ici par Henk van Boeijen pour couvrir vos besoins (vous devez faire défiler un peu vers le bas)
la source
Méthode d'extension utilisant la nouvelle contrainte Enum et les génériques pour empêcher la conversion:
la source
Vous pouvez le faire directement en convertissant en int mais vous perdrez la vérification de type. Je pense que la meilleure façon est d'utiliser quelque chose de similaire à ma proposition. Il garde le bon type tout le temps. Aucune conversion requise. Ce n'est pas parfait à cause de la boxe qui ajoutera un peu de succès aux performances.
Pas parfait (boxe), mais ça fait le boulot sans avertissement ...
Usage:
la source