net - if enum c#




Que signifie l'attribut Enum[Flags] en C#? (7)

@Nidonocu

Pour ajouter un autre indicateur à un ensemble de valeurs existant, utilisez l'opérateur d'affectation OR.

Mode = Mode.Read;
//Add Mode.Write
Mode |= Mode.Write;
Assert.True(((Mode & Mode.Write) == Mode.Write)
  && ((Mode & Mode.Read) == Mode.Read)));

De temps à autre, je vois une énumération comme celle-ci:

[Flags]
public enum Options 
{
    None    = 0,
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Option4 = 8
}

Je ne comprends pas ce que fait exactement l'attribut [Flags] .

Quelqu'un at-il une bonne explication ou un exemple à publier?


En combinant les réponses https://.com/a/8462/1037948 (déclaration via le transfert de bits) et https://.com/a/9117/1037948 (en utilisant des combinaisons dans la déclaration), vous pouvez décaler les valeurs précédentes plutôt que d'utiliser des chiffres. Pas nécessairement le recommander, mais juste en soulignant que vous pouvez.

Plutôt que:

[Flags]
public enum Options : byte
{
    None    = 0,
    One     = 1 << 0,   // 1
    Two     = 1 << 1,   // 2
    Three   = 1 << 2,   // 4
    Four    = 1 << 3,   // 8

    // combinations
    OneAndTwo = One | Two,
    OneTwoAndThree = One | Two | Three,
}

Vous pouvez déclarer

[Flags]
public enum Options : byte
{
    None    = 0,
    One     = 1 << 0,       // 1
    // now that value 1 is available, start shifting from there
    Two     = One << 1,     // 2
    Three   = Two << 1,     // 4
    Four    = Three << 1,   // 8

    // same combinations
    OneAndTwo = One | Two,
    OneTwoAndThree = One | Two | Three,
}

Confirmer avec LinqPad:

foreach(var e in Enum.GetValues(typeof(Options))) {
    string.Format("{0} = {1}", e.ToString(), (byte)e).Dump();
}

Résulte en:

None = 0
One = 1
Two = 2
OneAndTwo = 3
Three = 4
OneTwoAndThree = 7
Four = 8

Il y a quelque chose de trop verbeux à propos de la construction if ((x & y) == y)... particulier si x ET y sont tous les deux des ensembles composés de drapeaux et que vous voulez seulement savoir s'il y a chevauchement.

Dans ce cas, tout ce que vous avez vraiment besoin de savoir est s'il y a une valeur non nulle [1] après avoir bitmaské .

[1] Voir le commentaire de Jaime. Si nous étions authentiquement bitmasking , nous aurions seulement besoin de vérifier que le résultat était positif. Mais puisque les enum peuvent être négatives, même étrangement, lorsqu'elles sont combinées avec msdn , il est défensif de coder pour != 0 plutôt que > 0 .

Construire hors de la configuration de @ andnil ...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BitFlagPlay
{
    class Program
    {
        [Flags]
        public enum MyColor
        {
            Yellow = 0x01,
            Green = 0x02,
            Red = 0x04,
            Blue = 0x08
        }

        static void Main(string[] args)
        {
            var myColor = MyColor.Yellow | MyColor.Blue;
            var acceptableColors = MyColor.Yellow | MyColor.Red;

            Console.WriteLine((myColor & MyColor.Blue) != 0);     // True
            Console.WriteLine((myColor & MyColor.Red) != 0);      // False                
            Console.WriteLine((myColor & acceptableColors) != 0); // True
            // ... though only Yellow is shared.

            Console.WriteLine((myColor & MyColor.Green) != 0);    // Wait a minute... ;^D

            Console.Read();
        }
    }
}

J'ai demandé récemment quelque chose de similaire.

Si vous utilisez des indicateurs, vous pouvez ajouter une méthode d'extension à enums pour faciliter la vérification des indicateurs contenus (voir la publication pour plus de détails)

Cela vous permet de faire:

[Flags]
public enum PossibleOptions : byte
{
    None = 0,
    OptionOne = 1,
    OptionTwo = 2,
    OptionThree = 4,
    OptionFour = 8,

    //combinations can be in the enum too
    OptionOneAndTwo = OptionOne | OptionTwo,
    OptionOneTwoAndThree = OptionOne | OptionTwo | OptionThree,
    ...
}

Alors vous pouvez faire:

PossibleOptions opt = PossibleOptions.OptionOneTwoAndThree 

if( opt.IsSet( PossibleOptions.OptionOne ) ) {
    //optionOne is one of those set
}

Je trouve cela plus facile à lire que la plupart des moyens de vérifier les drapeaux inclus.


Les drapeaux vous permettent d'utiliser le masquage de bit à l'intérieur de votre énumération. Cela vous permet de combiner des valeurs d'énumération, tout en conservant celles qui sont spécifiées.

[Flags]
public enum DashboardItemPresentationProperties : long
{
    None = 0,
    HideCollapse = 1,
    HideDelete = 2,
    HideEdit = 4,
    HideOpenInNewWindow = 8,
    HideResetSource = 16,
    HideMenu = 32
}

Pour ajouter Mode.Write :

Mode = Mode | Mode.Write;

Vous pouvez aussi faire ça

[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3
}

Je trouve le bit-shift plus facile que de taper 4,8,16,32 et ainsi de suite. Cela n'a aucun impact sur votre code, car tout est fait au moment de la compilation







flags