[C#] 열거 형 권한에 종종 0, 1, 2, 4 값이있는 이유는 무엇입니까?

사람들은 왜 항상 열거 값이 좋아 사용 0, 1, 2, 4, 8하지 0, 1, 2, 3, 4?

비트 연산 등과 관련이 있습니까?

이것이 올바르게 사용되는 방법에 대한 작은 샘플 스 니펫에 감사드립니다. 🙂

[Flags]
public enum Permissions
{
    None   = 0,
    Read   = 1,
    Write  = 2,
    Delete = 4
}



답변

그들은 2의 거듭 제곱이고 나는 이것을 할 수 있기 때문에 :

var permissions = Permissions.Read | Permissions.Write;

아마 나중에 …

if( (permissions & Permissions.Write) == Permissions.Write )
{
    // we have write access
}

비트 필드이며, 각 세트 비트는 일부 권한 (또는 열거 된 값이 논리적으로 일치하는 것)에 해당합니다. 이것이 정의 된 1, 2, 3, ...경우이 방식으로 비트 연산자를 사용할 수없고 의미있는 결과를 얻을 수 없습니다. 더 깊이 탐구하려면 …

Permissions.Read   == 1 == 00000001
Permissions.Write  == 2 == 00000010
Permissions.Delete == 4 == 00000100

여기에 패턴이 있습니까? 이제 원래 예를 들어 보면

var permissions = Permissions.Read | Permissions.Write;

그때…

permissions == 00000011

보다? 모두 ReadWrite비트가 설정되고, 그 독립적으로 확인할 수 있습니다합니다 (있음 또한 통지 Delete비트가되어 있지 설정을하기 때문에이 값은 삭제할 수있는 권한을 전달하지 않습니다).

하나의 비트 필드에 여러 플래그를 저장할 수 있습니다.


답변

다른 답변에서 여전히 명확하지 않은 경우 다음과 같이 생각하십시오.

[Flags]
public enum Permissions
{
   None = 0,
   Read = 1,
   Write = 2,
   Delete = 4
} 

작성하는 더 짧은 방법입니다.

public enum Permissions
{
    DeleteNoWriteNoReadNo = 0,   // None
    DeleteNoWriteNoReadYes = 1,  // Read
    DeleteNoWriteYesReadNo = 2,  // Write
    DeleteNoWriteYesReadYes = 3, // Read + Write
    DeleteYesWriteNoReadNo = 4,   // Delete
    DeleteYesWriteNoReadYes = 5,  // Read + Delete
    DeleteYesWriteYesReadNo = 6,  // Write + Delete
    DeleteYesWriteYesReadYes = 7, // Read + Write + Delete
} 

여덟 가지 가능성이 있지만 네 멤버 만 조합하여 나타낼 수 있습니다. 16 개의 가능성이 있다면 5 명의 조합으로 나타낼 수 있습니다. 40 억 개의 가능성이 있다면 33 명의 조합으로 나타낼 수 있습니다! 열거 형에 40 억 개의 항목을 명명하려고 시도하는 것보다 각각 33의 구성원 (각 0을 제외하고)의 2 제곱을 갖는 것이 훨씬 낫습니다.


답변

이 값들은 이진수로 고유 한 비트 위치를 나타 내기 때문에 :

1 == binary 00000001
2 == binary 00000010
4 == binary 00000100

등등

1 | 2 == binary 00000011

편집하다:

3 == binary 00000011

이진수로 3은 1과 2의 위치에서 1의 값으로 표시됩니다. 실제로 값과 같습니다 1 | 2. 따라서 이진 자리를 플래그로 사용하여 일부 상태를 나타내는 경우 3은 의미가 없습니다 (실제로 두 값의 조합 인 논리적 값이없는 한)

더 명확히하기 위해 다음과 같이 예제 열거 형을 확장 할 수 있습니다.

[Flags]
public Enum Permissions
{
  None = 0,   // Binary 0000000
  Read = 1,   // Binary 0000001
  Write = 2,  // Binary 0000010
  Delete = 4, // Binary 0000100
  All = 7,    // Binary 0000111
}

따라서,에는 Permissions.All또한 암시 적 Permissions.Read으로 Permissions.Write, 및Permissions.Delete


답변

[Flags]
public Enum Permissions
{
    None   =    0; //0000000
    Read   =    1; //0000001
    Write  = 1<<1; //0000010
    Delete = 1<<2; //0000100
    Blah1  = 1<<3; //0001000
    Blah2  = 1<<4; //0010000
}

나는 이런 식으로 글을 이해하고 읽기가 더 쉽다고 생각하며 계산할 필요가 없습니다.


답변

이들은 열거 형 값의 조합을 허용하는 비트 플래그를 나타내는 데 사용됩니다. 16 진수 표기법으로 값을 쓰면 더 명확하다고 생각합니다.

[Flags]
public Enum Permissions
{
  None =  0x00,
  Read =  0x01,
  Write = 0x02,
  Delete= 0x04,
  Blah1 = 0x08,
  Blah2 = 0x10
}


답변

이것은 실제로 더 많은 주석이지만 형식을 지원하지 않기 때문에 플래그 열거를 설정하는 데 사용한 방법을 포함하고 싶었습니다.

[Flags]
public enum FlagTest
{
    None = 0,
    Read = 1,
    Write = Read * 2,
    Delete = Write * 2,
    ReadWrite = Read|Write
}

이 접근 방식은 플래그를 알파벳 순서로 유지하려는 경우 개발 중에 특히 유용합니다. 새 플래그 값을 추가해야한다고 결정한 경우 알파벳순으로 삽입 할 수 있으며 변경해야하는 유일한 값은 이전 값입니다.

그러나 솔루션이 프로덕션 시스템에 게시되면 (특히 웹 서비스와 같이 밀접한 결합없이 열거 형이 노출 된 경우) 열거 형 내의 기존 값을 변경하지 않는 것이 좋습니다.


답변

이것에 대한 좋은 답변이 많이 있습니다 … 그냥 말할 것입니다. 구문이 표현하려고하는 것을 좋아하지 않거나 쉽게 파악할 수없는 경우<< 개인적으로 대안을 선호합니다 (그리고 직접 열거 형 선언 스타일을 감히 말합니다 ) …

typedef NS_OPTIONS(NSUInteger, Align) {
    AlignLeft         = 00000001,
    AlignRight        = 00000010,
    AlignTop          = 00000100,
    AlignBottom       = 00001000,
    AlignTopLeft      = 00000101,
    AlignTopRight     = 00000110,
    AlignBottomLeft   = 00001001,
    AlignBottomRight  = 00001010
};

NSLog(@"%ld == %ld", AlignLeft | AlignBottom, AlignBottomLeft);

LOG 513 == 513

이해하기가 훨씬 쉬워졌습니다. 하나를 정렬하십시오… 원하는 결과를 설명하고, 원하는 결과를 얻으십시오. “계산”이 필요하지 않습니다.