Когда вы используете флаг (Enum), у вас есть предел 64. Какая альтернатива, когда вы достигаете предела?
С перечислением под .net самым большим числом, которое вы можете использовать, является ULong.
Это означает максимум 64 флага.
Какая альтернатива, если вам нужно больше 64 флагов?
Edit
Извините, я забыл добавить эту альтернативу, которая по-прежнему будет работать с побитовыми операциями, по крайней мере, такими; и и или.
используя предложение Джош Эйнштейна, я придумал это, имеет ли смысл?
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);
}
}
Ответы
Ответ 1
Затем вы можете переключиться на BitArray. Вы потеряете все "функции" перечисления, такие как форматирование строк и возможность синтаксического анализа по умолчанию. BitArray был бы в основном похож на наличие булевых полей, за исключением того, что хранилище намного эффективнее.
Действительно, как говорит Джефф в комментариях к этому множеству независимых состояний бит, похоже, что Enum - это неправильное решение. BitArray может быть гораздо более подходящим для вашего конкретного сценария.
Ответ 2
То, что многие флаги кажутся чрезмерными и предполагает, что необходима редизайн. Однако вы можете использовать два набора флагов. Первый обозначает "группа флагов", а второй - флаги внутри этой группы. Вы должны иметь класс, который затем управлял вашим "сгруппированным перечислением", чтобы вы могли проверить, был ли установлен флаг или нет.
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.
}
Ответ 3
Если вам нужно больше 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);
}
}