때때로 다음과 같은 열거형이 표시됩니다.
[Flags] public enum Options { None = 0, Option1 = 1, Option2 = 2, Option3 = 4, Option4 = 8 }
[Flags]
속성이 정확히 무엇을 하는지 이해하지 못합니다.
누구든지 게시 할 수있는 좋은 설명이나 예가 있습니까?
질문자 :Brian Leahy
때때로 다음과 같은 열거형이 표시됩니다.
[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]
가 자동으로 열거형 값을 2의 거듭제곱으로 만들지 않는다는 점에 유의하는 것도 중요합니다. 숫자 값을 생략하면 기본적으로 값이 0으로 시작하고 증분하기 때문에 열거형이 비트 연산에서 예상한 대로 작동하지 않습니다.
잘못된 선언:
[Flags] public enum MyColors { Yellow, // 0 Green, // 1 Red, // 2 Blue // 3 }
이런 식으로 값을 선언하면 노란색 = 0, 녹색 = 1, 빨간색 = 2, 파란색 = 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
마찬가지로, 당신은 바이너리 비트를 사용하여 빨강, 녹색, 파랑에 속성 AllowedColors을 설정 한 후 OR |
연산자, AllowedColors 는 다음과 같습니다.
myProperties.AllowedColors: 00001110
따라서 값을 검색할 때 실제로 값에 대해 비트 AND &
를 수행하고 있습니다.
myProperties.AllowedColors: 00001110 MyColor.Green: 00000010 ----------------------- 00000010 // Hey, this is the same as MyColor.Green!
없음 = 0 값
그리고 MSDN에서 인용한 귀하의 열거에서 0
을 사용하는 것과 관련하여:
[Flags] public enum MyColors { None = 0, .... }
값이 0인 플래그 열거 상수의 이름으로 None을 사용하십시오. 결과가 항상 0이기 때문에 비트 AND 연산에서 None 열거 상수를 사용하여 플래그를 테스트할 수 없습니다. 그러나 숫자 값과 None 열거 상수 간에 비트 단위가 아닌 논리 비교를 수행하여 숫자 값의 비트가 설정되었는지 여부를 확인할 수 있습니다.
msdn 에서 flags 속성과 사용법에 대한 자세한 정보를 찾을 수 있으며 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에서 열거형 플래그는 이진 리터럴을 사용하여 작성할 수 있습니다.
[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 }
포함된 플래그를 확인하는 대부분의 방법보다 이것이 읽기 쉽습니다.
플래그로 작업할 때 나는 종종 추가 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 }
@니도노쿠
기존 값 집합에 다른 플래그를 추가하려면 OR 할당 연산자를 사용합니다.
Mode = Mode.Read; //Add Mode.Write Mode |= Mode.Write; Assert.True(((Mode & Mode.Write) == Mode.Write) && ((Mode & Mode.Read) == Mode.Read)));
Mode.Write
를 추가하려면:
Mode = Mode | Mode.Write;
[정보] 나에게 지나치게 자세한 뭔가가있다 if ((x & y) == y)...
구조, 특히 x
와 y
플래그의 두 화합물 세트이고, 당신은 어떤 중복이 있는지 알고 싶습니다.
이 경우 비트마스크를 한 후 0이 아닌 값[1]이 있는지만 알아야 합니다.
[1] Jaime의 의견을 참조하십시오. 우리가 진정으로 비트마스킹 을 한다면 결과가 긍정적인지 확인하기만 하면 됩니다.
enum
s 는 음수가 될 수 있기 때문에[Flags]
속성> 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] public enum DashboardItemPresentationProperties : long { None = 0, HideCollapse = 1, HideDelete = 2, HideEdit = 4, HideOpenInNewWindow = 8, HideResetSource = 16, HideMenu = 32 }
누군가 이미 이 시나리오를 발견했다면 사과드립니다. 반사에서 볼 수 있는 플래그의 완벽한 예입니다. 예 바인딩 플래그 ENUM .
[System.Flags] [System.Runtime.InteropServices.ComVisible(true)] [System.Serializable] public enum BindingFlags
용법
// BindingFlags.InvokeMethod // Call a static method. Type t = typeof (TestClass); Console.WriteLine(); Console.WriteLine("Invoking a static method."); Console.WriteLine("-------------------------"); t.InvokeMember ("SayHello", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object [] {});
열거 가능한 값이 열거형 멤버의 컬렉션을 나타낼 때 플래그가 사용됩니다.
여기서는 비트 연산자를 사용합니다. | 그리고 &
예시
[Flags] public enum Sides { Left=0, Right=1, Top=2, Bottom=3 } Sides leftRight = Sides.Left | Sides.Right; Console.WriteLine (leftRight);//Left, Right string stringValue = leftRight.ToString(); Console.WriteLine (stringValue);//Left, Right Sides s = Sides.Left; s |= Sides.Right; Console.WriteLine (s);//Left, Right s ^= Sides.Right; // Toggles Sides.Right Console.WriteLine (s); //Left
출처 : http:www.stackoverflow.com/questions/8447/what-does-the-flags-enum-attribute-mean-in-c
React JSX 내부 루프 (0) | 2022.02.08 |
---|---|
const int*, const int * const 및 int const *의 차이점은 무엇입니까? (0) | 2022.02.08 |
Java 'for each' 루프는 어떻게 작동합니까? (0) | 2022.02.08 |
"javascript:void(0)"은(는) 무슨 뜻인가요? (0) | 2022.02.08 |
vim "sudo로 쓰기" 트릭은 어떻게 작동합니까? (0) | 2022.02.08 |