2010-03-03 6 views
10

Con enum sotto .net il numero più grande che è possibile utilizzare è ULong.
Questo significa un massimo di 64 flag.Quando usi flag (Enum) hai un limite di 64. Quali sono le alternative quando raggiungi il limite?

Quale sarebbe l'alternativa quando sono necessarie più di 64 bandiere?

Modifica

Siamo spiacenti, ho dimenticato di aggiungere questo, un'alternativa che avrebbe ancora lavorare con operazioni bit per bit almeno questi uno; e e o.

utilizzando Josh Einstein suggerimento, mi sono inventato questo, ha senso?

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

Una riprogettazione? Quante bandiere sembrano troppo complesse. –

+0

finora ho solo 31 flag, ma voglio solo assicurarmi di avere un piano di backup pronto se è necessario – Fredou

+3

YAGNI viene in mente. Concentrati sui problemi che hai. –

risposta

5

È quindi possibile passare all'utilizzo di BitArray. Si perderebbero tutte le "caratteristiche" di una enumerazione come la formattazione della stringa predefinita e l'abilità di analisi. Un BitArray sarebbe fondamentalmente simile ad avere un sacco di campi booleani, tranne che lo storage è molto più efficiente.

Infatti, come dice Jeff nei commenti con molti stati di bit indipendenti, sembra comunque che un Enum sia la soluzione sbagliata. Un BitArray potrebbe essere molto più adatto per il tuo particolare scenario.

+0

finora questa sembra essere la migliore alternativa, dal momento che non riesco davvero a raggruppare la mia bandiera – Fredou

+0

puoi guardare la mia domanda aggiornata e dirmi se questo è quello che avevi in ​​mente? – Fredou

+0

Ci scusiamo per il ritardo. Puoi usare un singolo BitArray per contenere tutte le bandiere che vuoi. var bits = new BitArray (new bool [255]); bits.Set (50, true); bits.Get (50); ecc ... Probabilmente vorrai definire le posizioni dei bit in un enum tradizionale (non-flags) che può contenere tanti valori come il suo tipo sottostante. In altre parole bits.Set (MyFlags.Flag50, true); – Josh

7

Quante bandiere sembrano eccessive e suggerirebbero una riprogettazione. Tuttavia, potresti prendere in considerazione l'utilizzo di due serie di flag. Il primo a designare il "gruppo flag" e il secondo a designare i flag all'interno di quel gruppo. Dovresti avere una classe che gestisca il tuo "enum raggruppato" in modo da poter verificare se una bandiera è stata impostata o meno in un modo semplice.

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

purtroppo non riesco a raggrupparli correttamente. – Fredou

+0

@Fredou: potresti rimanere incantato dalla terminologia. "Gruppo" è solo un termine che ho usato, ciò che è veramente è un modo per estendere il numero di flag che è possibile utilizzare. Considera "gruppo" come la parte più importante delle tue bandiere. –

0

Quando sono necessari più di 64 flag, è possibile utilizzare la versione a 128 bandiere.

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); 
    } 
} 
Problemi correlati