2010-03-03 4 views
10

Avec enum sous .net le plus grand nombre que vous pouvez utiliser est ULong.
Cela signifie un maximum de 64 drapeaux.Lorsque vous utilisez flag (Enum) vous avez une limite de 64. Quelles sont les alternatives lorsque vous atteignez la limite?

Quelle serait l'alternative lorsque vous avez besoin de plus de 64 drapeaux?

Modifier

Désolé, j'oublié d'ajouter cette alternative qui fonctionne toujours avec opérations au niveau du bit au moins ces un; et et ou.

en utilisant Josh Einstein suggestion, je suis venu avec cela, est-ce logique?

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

Une refonte? Que de nombreux drapeaux semblent trop complexes. –

+0

jusqu'ici j'ai seulement 31 drapeaux, mais je veux juste m'assurer que j'ai un plan de secours prêt si c'est nécessaire – Fredou

+3

YAGNI vient à l'esprit. Concentrez-vous sur les problèmes que vous avez. –

Répondre

5

Vous pouvez ensuite passer à l'aide d'un BitArray. Vous perdriez toutes les "caractéristiques" d'une énumération telle que la capacité de mise en forme et d'analyse de chaîne par défaut. Un BitArray serait fondamentalement similaire à un tas de champs booléens sauf que le stockage est beaucoup plus efficace.

En effet, comme Jeff dit dans les commentaires avec autant d'états de bits indépendants, il semble que Enum est une mauvaise solution de toute façon. Un BitArray peut être beaucoup plus adapté à votre scénario particulier.

+0

jusqu'ici cela semble être la meilleure alternative, puisque je ne peux pas vraiment grouper mon drapeau – Fredou

+0

pouvez-vous regarder ma question mise à jour et dites-moi si c'est ce que vous aviez en tête? – Fredou

+0

Désolé pour le retard. Vous pouvez utiliser un seul BitArray pour stocker autant de drapeaux que vous le souhaitez. var bits = new BitArray (nouveau bool [255]); bits.Set (50, vrai); bits.Get (50); etc ... Vous voudrez probablement définir les positions de bits dans une énumération traditionnelle (non-flags) qui peut contenir autant de valeurs que son type sous-jacent. En d'autres termes bits.Set (MyFlags.Flag50, true); – Josh

7

Que de nombreux drapeaux semblent excessifs et suggèrent une refonte est nécessaire. Cependant, vous pourriez envisager d'utiliser deux ensembles de drapeaux. Le premier à désigner le «groupe de drapeau» et le second à désigner les drapeaux de ce groupe. Vous auriez dû avoir une classe qui a ensuite géré votre "énumération groupée" afin que vous puissiez tester si un drapeau a été défini ou non d'une manière simple.

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

malheureusement, je ne peux pas vraiment les grouper – Fredou

+0

@Fredou: Vous pouvez être accroché sur la terminologie. "Groupe" est juste un terme que j'ai utilisé, ce que c'est vraiment une façon d'augmenter le nombre de drapeaux que vous pouvez utiliser. Considérez «groupe» comme étant la partie la plus élevée de vos drapeaux. –

0

Lorsque vous avez besoin de plus de 64 drapeaux, vous pouvez utiliser la version 128-drapeaux.

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); 
    } 
} 
Questions connexes