Как очистить старшие байты в C# Flags Enum
Я использую Flags Enum для отслеживания этапов завершения процесса переноса данных для каждой записи данных. Мне нужен способ вернуться к указанному этапу, где я могу начать повторную обработку миграции записи данных. Как сбросить старшие байты в перечислении Flags?
Пример Enum:
[Flags]
public Enum MigrationStages {
None = 0,
Started = 1,
MiddleStage = 2,
WrappingUp = 4,
Finished = 8
}
Моя текущая стоимость:
var currentStage =
MigrationStages.None
| MigrationStages.Started
| MigrationStages.MiddleStage
| MigrationStages.WrappingUp
| MigrationStages.Finished;
Я хочу сбросить обратно MigrationStages.MiddleStage
вызывать повторную обработку, начинающуюся там.
2 ответа
Побитовая математика - это не то, что мы больше используем. Поэтому, когда я отправился на поиски ответа на этот вопрос, я не нашел ничего, что могло бы помочь, поэтому я решил это. Делить мою математику с миром на случай, если другие сочтут это полезным.
Для этого я создал простой вспомогательный метод:
public static MigrationStage ClearHigherFlags(MigrationStage orig, MigrationStage highBit)
{
var lowerBits = (int)orig % (int)highBit;
return highBit + lowerBits;
}
Пример использования:
currentStage = ClearHigherFlags(currentStage, MigrationStages.MiddleStage);
Очевидно, что если вы хотите снять более высокие флаги, включая highBit
только не добавляйте это обратно. Очистить нижние флаги, return orig - lowerBits
,
Поразрядная математика, модуль (%
) часто твой друг.
добавление
Есть те, кто найдет этот ответ и подумает, что это не совсем математика. Я надеюсь, что это успокаивает тех людей.
Во-первых, напомним, что это флаги, о которых мы говорим, поэтому это очень специфическое подмножество битовых манипуляций, где модуль облегчает чтение математики и очень уместен. Фактическая математика, выполняемая заменой компилятора, будет выглядеть примерно так, что я считаю гораздо менее интуитивно понятным для чтения.
public static MigrationStage ClearHigherFlags(MigrationStage orig, MigrationStage highBit)
{
var bitMask = highBit - 1;
var lowerBits = orig & bitMask;
return highBit + lowerBits;
}
Это действительно не так сложно читать, но преобразование в битовую маску сделано неявно в моем первоначальном решении.
Если вы хотите использовать побитовую манипуляцию, вы можете сделать это следующим образом:
var lowbits = MigrationStages.MiddleStage | MigrationStages.Started;
Затем очистите старшие биты в вашем примере:
currentStage = currentStage & lowbits;
Может быть, это будет иметь больше смысла:
8 4 2 1
==========
lowbits 0 0 1 1
currentvalue 1 1 1 1
==========
AND (&) 0 0 1 1
который очищает два старших бита