2010-03-03 2 views
10

enum .net에서 사용할 수있는 가장 큰 숫자는 ULong입니다.
최대 64 개의 플래그를 의미합니다.플래그 (열거 형)를 사용할 때 한계는 64입니다. 한도에 도달하면 대안은 무엇입니까?

64 개 이상의 플래그가 필요할 때 대체 방법은 무엇입니까?

편집이

미안 해요, 난이 추가 깜빡 여전히 비트 연산 이상이 하나를 작동 할 대안; 또는이다.

조쉬 아인슈타인 제안을 사용하면이 점이 마음에 듭니까?

class bitArrayFlag 
{ 
    private const int flagSize = 255; //allow X numbers of flags 

    public BitArray flag1; 
    public BitArray flag2; 
    public BitArray flagN; 

    public bitArrayFlag() 
    { 
     int flagPos = 0; 
     bool[] flagBit = new bool[flagSize]; 

     flagBit[flagPos] = true; 
     flag1 = new BitArray(flagBit); 

     flagBit[flagPos] = false; 
     flagPos += 1; 
     flagBit[flagPos] = true; 
     flag2 = new BitArray(flagBit); 

     //... 
     //... 
     //... 

     flagBit[flagPos] = false; 
     flagPos += 1; 
     flagBit[flagPos] = true; 
     flagN = new BitArray(flagBit); 
    } 
} 
+8

재 설계? 그 많은 깃발은 지나치게 복잡하게 들립니다. –

+0

지금까지 31 개 플래그 만 가지고 있지만 필요할 경우 백업 계획을 준비하고 싶습니다. – Fredou

+3

YAGNI가 마음에 듭니다. 당신이 가진 문제에 집중하십시오. –

답변

5

그런 다음 BitArray을 사용하여 전환 할 수 있습니다. 기본 문자열 형식 지정 및 구문 분석 기능과 같은 열거 형의 "기능"을 모두 잃게됩니다. BitArray는 저장소가 훨씬 더 효율적이라는 점을 제외하고는 부울 필드가 많이있는 것과 근본적으로 비슷합니다.

사실 제프는 많은 독립 비트 상태에 대한 의견에서 Enum은 잘못된 해결책이라고 생각합니다. BitArray는 특정 시나리오에 더 적합 할 수 있습니다.

+0

지금까지 내 깃발을 그룹으로 묶을 수 없기 때문에 이것이 최고의 대안 인 것 같습니다. – Fredou

+0

업데이트 된 질문을보고 이것이 마음에 들었는지 말해 줄 수 있습니까? – Fredou

+0

지연되어서 죄송합니다. 단일 BitArray를 사용하여 원하는만큼의 플래그를 유지할 수 있습니다. var bits = 새로운 BitArray (새로운 bool [255]); bits.Set (50, true); bits.Get (50); 등등 ... 기본 유형과 같은 값을 가질 수있는 전통적인 (플래그가 아닌) 열거 형의 비트 위치를 정의하려고합니다. 즉, bits.Set (MyFlags.Flag50, true); – Josh

7

많은 플래그가 과도하게 보이며 재 설계가 필요하다는 것을 나타냅니다. 그러나 두 개의 플래그 세트 사용을 고려할 수 있습니다. 첫 번째는 "플래그 그룹"을 지정하고 두 번째는 해당 그룹 내의 플래그를 지정합니다. 플래그가 설정되었는지 여부를 간단한 방법으로 테스트 할 수 있도록 "그룹화 된 열거 형"을 관리하는 클래스가 있어야합니다.

struct BigFlags<TGroupEnum, TFlagEnum> 
{ 
    private Dictionary<TGroupEnum, TFlagEnum> flags; 

    public BigFlags(IDictionary<TGroupEnum, TFlagEnum> flags) 
    { 
     this.flags = new Dictionary<TGroupEnum, TFlagEnum>(flags); 
    } 

    public BigFlags(TGroupEnum group, TFlagEnum flags) 
    { 
     this.flags = new Dictionary<TGroupEnum, TFlagEnum>() { { group, flags } }; 
    } 

    public bool Contains(BigFlags<TGroupEnum, TFlagEnum> flags) 
    { 
     // TODO: Compare dictionaries and see if the passed flags are a subset of these flags. 
    } 

    // TODO: Equality to check exact match 
    // TODO: Logical operators and operators for setting/removing flags. 
} 
+0

슬프게도, 나는 그들을 그룹으로 묶을 수 없다. – Fredou

+0

@ Fredou : 당신은 용어에 매달려 있을지도 모른다. "그룹"은 제가 사용했던 용어 일뿐입니다. 실제로 사용할 수있는 플래그의 수를 늘리는 방법입니다. "group"을 플래그의 고위 부분으로 간주하십시오. –

0

64 개 이상의 플래그가 필요한 경우 128 플래그 버전을 사용할 수 있습니다.

public class BigFlags<TEnumHi, TEnumLo> 
{ 
    private long _hi; 
    private long _lo; 

    public bool HasFlags(TEnumHi value) 
    { 
     var hiValue = (long)(object)value; 

     return (_hi & hiValue) == hiValue; 
    } 

    public bool HasFlags(TEnumLo value) 
    { 
     var loValue = (long)(object)value; 

     return (_lo & loValue) == loValue; 
    } 

    public bool HasFlags(TEnumHi hiPart, TEnumLo loPart) 
    { 
     return HasFlags(hiPart) && HasFlags(loPart); 
    } 

    public void SetFlags(TEnumHi value) 
    { 
     var hiValue = (long)(object)value; 

     _hi = _hi | hiValue; 
    } 

    public void SetFlags(TEnumLo value) 
    { 
     var loValue = (long)(object)value; 

     _lo = _lo | loValue; 
    } 

    public override string ToString() 
    { 
     var hiEnum = ((TEnumHi)(object)_hi).ToString(); 
     var loEnum = ((TEnumLo)(object)_lo).ToString(); 

     if (hiEnum.Length == 0) 
     { 
      return loEnum; 
     } 

     if (loEnum.Length == 0) 
     { 
      return hiEnum; 
     } 

     return string.Concat(hiEnum, " , ", loEnum); 
    } 
} 
관련 문제