Как очистить старшие байты в 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

который очищает два старших бита

Другие вопросы по тегам