220 votes

Opérations au format C # les plus courantes sur les enums

Pour la vie de moi, je ne me souviens pas comment définir, supprimer, basculer ou tester un peu dans un champ de bits. Soit je ne suis pas sûr ou je les mélange parce que j'en ai rarement besoin. Donc, un "bit-triche-feuille" serait bien d'avoir.

Par exemple:

 flags = flags | FlagsEnum.Bit4;  // Set bit 4.
 

ou

 if ((flags & FlagsEnum.Bit4)) == FlagsEnum.Bit4) // Is there a less verbose way?
 

Pouvez-vous donner des exemples de toutes les autres opérations communes, de préférence en syntaxe C # en utilisant une énumération [Flags]?

298voto

Hugoware Points 13645

J'ai fait un peu plus de travail sur ces extensions - Vous pouvez trouver le code ici

J'ai écrit des méthodes d'extension qui étendent System.Enum que j'utilise souvent ... Je ne prétends pas qu'ils sont à l'épreuve des balles, mais ils ont aidé ... Les commentaires ont été supprimés ...

 namespace Enum.Extensions {

    public static class EnumerationExtensions {

        public static bool Has<T>(this System.Enum type, T value) {
            try {
                return (((int)(object)type & (int)(object)value) == (int)(object)value);
            } 
            catch {
                return false;
            }
        }

        public static bool Is<T>(this System.Enum type, T value) {
            try {
                return (int)(object)type == (int)(object)value;
            }
            catch {
                return false;
            }    
        }


        public static T Add<T>(this System.Enum type, T value) {
            try {
                return (T)(object)(((int)(object)type | (int)(object)value));
            }
            catch(Exception ex) {
                throw new ArgumentException(
                    string.Format(
                        "Could not append value from enumerated type '{0}'.",
                        typeof(T).Name
                        ), ex);
            }    
        }


        public static T Remove<T>(this System.Enum type, T value) {
            try {
                return (T)(object)(((int)(object)type & ~(int)(object)value));
            }
            catch (Exception ex) {
                throw new ArgumentException(
                    string.Format(
                        "Could not remove value from enumerated type '{0}'.",
                        typeof(T).Name
                        ), ex);
            }  
        }

    }
}
 

Ensuite, ils sont utilisés comme suit

 SomeType value = SomeType.Grapes;
bool isGrapes = value.Is(SomeType.Grapes); //true
bool hasGrapes = value.Has(SomeType.Grapes); //true

value = value.Add(SomeType.Oranges);
value = value.Add(SomeType.Apples);
value = value.Remove(SomeType.Grapes);

bool hasOranges = value.Has(SomeType.Oranges); //true
bool isApples = value.Is(SomeType.Apples); //false
bool hasGrapes = value.Has(SomeType.Grapes); //false
 

119voto

Drew Noakes Points 69288

Dans .NET 4, vous pouvez maintenant écrire:

 flags.HasFlag(FlagsEnum.Bit4)
 

98voto

Stephen Deken Points 2418

L’idiome est d’utiliser l’opérateur ou égal pour définir les bits :

Pour effacer un peu, l’idiome est d’utiliser au niveau du bit et avec la négation :

Parfois, vous avez un décalage qui identifie votre foret, et puis l’idiome est d’utiliser ces combinés avec décalage vers la gauche :

34voto

22voto

wraith808 Points 378

@Drew

Veuillez noter que, sauf dans le plus simple des cas, la Enum.HasFlag porte une altération des performances lourd par rapport à écrire manuellement le code. Examinons le code suivant :

Plus 10 millions d’itérations, la méthode d’extension HasFlags prend un énorme ms 4793, par rapport aux 27 États membres pour la mise en œuvre au niveau du bit standard.

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