当您使用旗帜(Enum)时,您的限制为64.达到限制时有哪些替代方案?

时间:2010-03-03 14:52:16

标签: .net

在.net下使用枚举,您可以使用的最大数字是ULong 这意味着最多64个标志。

当您需要超过64个标志时,还有什么选择?

修改

对不起,我忘了添加这个,这个替代方案仍然适用于按位操作至少这一个; 以及

使用 Josh Einstein 建议,我想出了这个,它有意义吗?

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

3 个答案:

答案 0 :(得分: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.
}

答案 1 :(得分:5)

然后您可以切换到使用BitArray。您将丢失枚举的所有“功能”,例如默认字符串格式和解析功能。 BitArray基本上类似于拥有一堆布尔字段,除了存储效率更高。

事实上,正如Jeff在评论中所说的许多独立位状态一样,看起来Enum是错误的解决方案。 BitArray可能更适合您的特定场景。

答案 2 :(得分: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);
    }
}