때때로 나는 다음과 같은 열거 형을 봅니다.
[Flags]
public enum Options
{
None = 0,
Option1 = 1,
Option2 = 2,
Option3 = 4,
Option4 = 8
}
[Flags]
속성이 정확히 무엇인지 이해 하지 못합니다.
누구나 좋은 설명이나 예를 게시 할 수 있습니까?
답변
[Flags]
열거 가능한 오히려 단일 값보다도, 가능한 값들의 집합을 나타낸다마다 속성이 사용되어야한다. 이러한 컬렉션은 종종 비트 연산자와 함께 사용됩니다.
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
이 [Flags]
속성 자체로는이 기능을 사용할 수 없습니다. 이 방법만으로도 .ToString()
메소드를 멋지게 표현할 수 있습니다 .
enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
[Flags] enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
...
var str1 = (Suits.Spades | Suits.Diamonds).ToString();
// "5"
var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();
// "Spades, Diamonds"
또한 노트에 중요 [Flags]
하지 않습니다 자동으로 두 가지의 열거 값 능력을합니다. 숫자 값을 생략하면 기본적으로 값이 0으로 시작하고 증가하기 때문에 비트 연산에서 예상 할 수있는 것처럼 열거 형이 작동하지 않습니다.
잘못된 선언 :
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
이 방법으로 선언 된 값은 Yellow = 0, Green = 1, Red = 2, Blue = 3입니다. 이렇게하면 값을 플래그로 사용할 수 없게됩니다.
올바른 선언의 예는 다음과 같습니다.
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
속성에서 고유 한 값을 검색하려면 다음을 수행하십시오.
if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}
또는 .NET 4 : 이전
if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}
if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}
덮개 아래
열거 형에 2의 거듭 제곱을 사용했기 때문에 작동합니다. 표지 아래에서 열거 형 값은 이진수 1과 0으로 표시됩니다.
Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000
마찬가지로 이진 비트 OR 연산자를 사용하여 AllowedColors 속성 을 빨강, 녹색 및 파랑으로 설정하면 AllowedColors 는 다음과 같습니다.|
myProperties.AllowedColors: 00001110
따라서 값을 검색하면 실제로 &
값에 대해 비트 단위 AND 를 수행 합니다.
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
None = 0 값
그리고 0
MSDN에서 인용하여 열거에서 사용하는 것과 관련하여 :
[Flags]
public enum MyColors
{
None = 0,
....
}
값이 0 인 플래그 열거 상수의 이름으로 None을 사용하십시오. 결과가 항상 0이므로 비트 AND 연산에서 None 열거 상수를 사용하여 플래그를 테스트 할 수 없습니다. 그러나 숫자 값의 비트가 설정되어 있는지 여부를 확인하기 위해 숫자 값과 없음 열거 상수 사이의 비트 단위가 아닌 논리적 비교를 수행 할 수 있습니다.
당신은 더 플래그 특성에 대한 정보와에서의 사용을 찾을 수 MSDN 및 MSDN에서 설계 플래그
답변
당신은 또한 이것을 할 수 있습니다
[Flags]
public enum MyEnum
{
None = 0,
First = 1 << 0,
Second = 1 << 1,
Third = 1 << 2,
Fourth = 1 << 3
}
4,8,16,32 등을 입력하는 것보다 비트 시프 팅이 더 쉽다는 것을 알았습니다. 컴파일 타임에 모두 수행되므로 코드에 영향을 미치지 않습니다.
답변
답변 https://stackoverflow.com/a/8462/1037948 (비트 시프 팅을 통한 선언) 및 https://stackoverflow.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
답변
선언 및 잠재적 사용법을 보여주는 예는 다음을 참조하십시오.
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");
}
}
}
}
답변
C # 7에서 허용 된 답변 외에도 enum 플래그는 이진 리터럴을 사용하여 작성할 수 있습니다.
[Flags]
public enum MyColors
{
None = 0b0000,
Yellow = 0b0001,
Green = 0b0010,
Red = 0b0100,
Blue = 0b1000
}
이 표현을 통해 표지 아래에서 플래그가 어떻게 작동하는지 명확하게 생각합니다 .
답변
플래그를 사용하는 경우 포함 된 플래그를 쉽게 확인할 수 있도록 확장 메소드를 열거 형에 추가 할 수 있습니다 (자세한 내용은 포스트 참조).
이를 통해 다음을 수행 할 수 있습니다.
[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
}
포함 된 플래그를 확인하는 대부분의 방법보다 읽기 쉽습니다.
답변
N
기존 값 세트에 다른 플래그를 추가하려면 OR 대입 연산자를 사용하십시오.
Mode = Mode.Read;
//Add Mode.Write
Mode |= Mode.Write;
Assert.True(((Mode & Mode.Write) == Mode.Write)
&& ((Mode & Mode.Read) == Mode.Read)));
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)