属性 - enum c# int



[Flags] Enum AttributeはC#で何を意味しますか? (8)

時々、次のような列挙型が表示されます。

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

[Flags]属性の正確な動作がわかりません。

投稿できる良い説明や例はありますか?


Answer #1

最近 、似たようなことについて尋ねました

フラグを使用する場合は、列挙型に拡張メソッドを追加して、含まれているフラグのチェックを容易にすることができます(詳細については投稿を参照してください)

これにより、次のことが可能になります。

[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,
    ...
}

その後、次のことができます。

PossibleOptions opt = PossibleOptions.OptionOneTwoAndThree 

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

これは、含まれているフラグをチェックするほとんどの方法よりも読みやすいと思います。


Answer #2

Mode.Writeを追加するには:

Mode = Mode | Mode.Write;

Answer #3

if ((x & y) == y)...コンストラクトについて非常に冗長なものがありif ((x & y) == y)...特にxyが両方とも複合フラグセットであり重複があるかどうかだけを知りたい場合です。

この場合、 ビットマスクした後にゼロ以外の値[1]があるかどうかを本当に知る必要があります

[1] Jaimeのコメントを参照してください。 真にビットマスクを使用していた場合、結果が正であることを確認するだけで済みます。 しかしmsdnと組み合わせた場合、 enumは負になり、奇妙なことにもなるため、 > 0ではなく!= 0をコーディングする方が適切です。

@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();
        }
    }
}

Answer #4

これもできます

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

ビットシフトは、4、8、16、32などを入力するよりも簡単です。 すべてコンパイル時に行われるため、コードには影響しません。


Answer #5

フラグを使用すると、列挙内でビットマスクを使用できます。 これにより、指定された値を保持しながら、列挙値を組み合わせることができます。

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

Answer #6

フラグを操作するとき、追加のNoneおよびAllアイテムをしばしば宣言します。 これらは、すべてのフラグが設定されているか、フラグが設定されていないかを確認するのに役立ちます。

[Flags] 
enum SuitsFlags { 

    None =     0,

    Spades =   1 << 0, 
    Clubs =    1 << 1, 
    Diamonds = 1 << 2, 
    Hearts =   1 << 3,

    All =      ~(~0 << 4)

}

使用法:

Spades | Clubs | Diamonds | Hearts == All  // true
Spades & Clubs == None  // true


更新2019-10:

C#7.0以降では、バイナリリテラルを使用できます。これは、おそらくより読みやすいです。

[Flags] 
enum SuitsFlags { 

    None =     0b0000,

    Spades =   0b0001, 
    Clubs =    0b0010, 
    Diamonds = 0b0100, 
    Hearts =   0b1000,

    All =      0b1111

}

Answer #7

回答https://.com/a/8462/1037948 (ビットシフトによる宣言)とhttps://.com/a/9117/1037948 (宣言での組み合わせを使用)を組み合わせることで、以前の値をビットシフトできます数字を使うより。 必ずしもそれを推奨するわけではありませんが、単に指摘することができます。

のではなく:

[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,
}

宣言できます

[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,
}

LinqPadによる確認:

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

結果:

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

Answer #8

宣言と潜在的な使用法を示す例については、以下を参照してください。

namespace Flags
{
    class Program
    {
        [Flags]
        public enum MyFlags : short
        {
            Foo = 0x1,
            Bar = 0x2,
            Baz = 0x4
        }

        static void Main(string[] args)
        {
            MyFlags fooBar = MyFlags.Foo | MyFlags.Bar;

            if ((fooBar & MyFlags.Foo) == MyFlags.Foo)
            {
                Console.WriteLine("Item has Foo flag set");
            }
        }
    }
}




flags