c# - 자바 - 프로그래밍 enum




C#에서[Flags] 열거 형 속성의 의미는 무엇입니까? (8)

C # 7에서 허용 된 답변 외에도 enum 플래그는 이진 리터럴을 사용하여 작성할 수 있습니다.

[Flags]
public enum MyColors
{
    None   = 0b0000,
    Yellow = 0b0001,
    Green  = 0b0010,
    Red    = 0b0100,
    Blue   = 0b1000
}

이 표현을 통해 표지 아래에서 플래그가 어떻게 작동하는지 명확하게 생각합니다.

때때로 나는 다음과 같은 열거 형을 봅니다.

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

[Flags] -attribute가 정확히 무엇을하는지 이해할 수 없습니다.

누구나 좋은 설명이나 예를 게시 할 수 있습니까?


N

기존 값 세트에 다른 플래그를 추가하려면 OR 대입 연산자를 사용하십시오.

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

당신은 또한 이것을 할 수 있습니다

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

4,8,16,32 등을 입력하는 것보다 비트 시프 팅이 더 쉽다는 것을 알았습니다. 컴파일 타임에 모두 수행되므로 코드에 영향을 미치지 않습니다.


선언 및 잠재적 사용법을 보여주는 예는 다음을 참조하십시오.

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");
            }
        }
    }
}

응답을 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

플래그로 작업 할 때 종종 추가 없음 및 모든 항목을 선언합니다. 모든 플래그가 설정되어 있는지 또는 플래그가 설정되어 있지 않은지 확인하는 데 도움이됩니다.

[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

}

Mode.Write 를 추가하려면 :

Mode = Mode | Mode.Write;

if ((x & y) == y)... 구문에 대해 지나치게 장황한 것이 있습니다. 특히 xy 가 모두 복합 플래그 집합이고 겹치는 부분 만 알고 싶다면.

이 경우, 여러분이 정말로 알아야 할 것은 bitmasked 후 0이 아닌 값 [1]이 있는지 여부 입니다.

[1] Jaime의 의견을 참조하십시오. 우리가 진정으로 비트 마스킹 했다면 결과가 긍정적인지 확인하기 만하면 됩니다. 그러나 enum msdn 과 결합 될 때 음수 일 수도 있고, 이상하게도 음수 일 수 있기 때문에 > 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();
        }
    }
}




flags