在.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);
}
}
答案 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);
}
}