2010-03-03 112 views
10

With enum在.net下你可以使用的最大號碼是ULong。
這意味着最多64個標誌。當你使用標誌(Enum)時,你有一個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

重新設計?許多標誌聽起來過於複雜。 – 2010-03-03 14:54:49

+0

到目前爲止我只有31個標誌,但我只是想確保我有一個備份計劃,如果需要的話 – Fredou 2010-03-03 14:58:48

+3

YAGNI浮現在腦海。集中精力解決你的問題。 – 2012-04-20 21:18:50

回答

5

然後,您可以切換到使用BitArray。你會失去一個枚舉的所有「特性」,比如默認的字符串格式和解析能力。除了存儲效率更高之外,BitArray與基本類似於具有一堆布爾字段。

確實如同傑夫在評論中說的那樣,許多獨立的位狀態看起來好像Enum是錯誤的解決方案。 BitArray可能更適合您的特定場景。

+0

到目前爲止,這似乎是最好的選擇,因爲我不能真正組我的國旗 – Fredou 2010-03-03 16:41:41

+0

你可以看看我更新的問題,並告訴我,如果這是你的想法? – Fredou 2010-03-03 17:03:22

+0

對不起。您可以使用一個BitArray來保存任意數量的標誌。 var bits = new BitArray(new bool [255]); (50,true); bits.Get(50);等等...您可能想要在傳統(非標誌)枚舉中定義位位置,該枚舉可以保存與其基礎類型一樣多的值。換句話說bits.Set(MyFlags.Flag50,true); – Josh 2010-03-05 02:27:05

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 2010-03-03 17:04:30

+0

@Fredou:你可能會被掛上術語。 「Group」只是我用過的一個術語,它實際上是一種擴展可以使用的標誌數量的方法。考慮「組」是你的標誌的高階部分。 – 2010-03-03 17:36:56

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); 
    } 
} 
相關問題