Switch-Case с перечислением С#

318
10 июня 2017, 12:21

Такая проблема. Есть перечисление

[Flags]
public enum SortType
{
    Amount = 0,
    Consumptions = 1,
    Date = 2,
    Description = 3,
    Group = 4,
    Incomes = 5,
    Kind = 6, 
    Counterparty = 7,
    Type = 8,
    Valute = 9
}

По не му нужно пройтись switch-caseом, учитывая компоновку, потому что нужно выбрать множество вариантов для сортировки, но при некоторых раскладах, вроде следующего, появляется ошибка:

case SortType.Consumptions:
    break;
case SortType.Consumptions | SortType.Date:
    break;
//Предложение Switch содержит несколько случаев со значением "3" (Откуда, если в данном контексте оно впервые?)
case SortType.Consumptions | SortType.Description:
    break;
case SortType.Consumptions | SortType.Group:
    break;
//Предложение Switch содержит несколько случаев со значением "5" (То же самое)
case SortType.Consumptions | SortType.Incomes:

И так повторяется на каждое нечётное число. Хотя в похожем коде (вместо Consumprions стоит Amount) ошибок нет. Что делать?

Answer 1

Чтобы корректно работали побитовые операции, каждый флаг должен занимать свой отдельный бит:

[Flags]
public enum SortType
{
    Amount = 0,
    Consumptions = 1 << 0,
    Date = 1 << 1,
    Description = 1 << 2,
    Group = 1 << 3,
    Incomes = 1 << 4,
    Kind = 1 << 5, 
    Counterparty = 1 << 6,
    Type = 1 << 7,
    Valute = 1 << 8
}

Иначе получается что, например, Description - это уже побитовое пересечение Consumptions и Date.

Answer 2

При работе с флагами, желательно, чтобы значения соответствовали отдельным битам, например:

1 (0b0000001)
2 (0b0000010)
4 (0b0000100)
8 (0b0001000)

и т.д.

Это позволит при использовании битового ИЛИ получать одно значение, соответствующее сразу двум флагам, при этом это значение будет уникальным для любой комбинации флагов и по нему всегда можно будет сказать, с помощью каких флагов оно образовано.

В вопросе, значения перечисления идут по порядку, в связи с этим возникают коллизии, когда одно значение можно получить несколькими способами, например:

Incomes = 5
Consumptions | Group = 5
Date | Description = 5

Именно на это и ругается switch.

В связи с этим может возникнуть вопрос, а что же делает атрибут Flags, собственно, ничего не делает

READ ALSO
протокол SmtpClient

протокол SmtpClient

С каким протоколом транспортного уровня работает класс SmtpClient с udp или tcp или каким то еще? И можно ли как то повлиять на выбор этого протокола?

218
Событие Elapsed Таймера

Событие Elapsed Таймера

Делаю секундомер который должен работать в отдельном от GUI потоке, но выводить в label времяСекундомер должен работать параллельно остальным...

202
Ошибка при запуске nw.js [0607/131754:ERROR:process_info.cc(608)] range at 0x8b0b1d4600000000, size 0x32 fully unreadable

Ошибка при запуске nw.js [0607/131754:ERROR:process_info.cc(608)] range at 0x8b0b1d4600000000, size 0x32 fully unreadable

Кто-нибудь сталкивался с такой ошибкой при работе с nwjs? [0607/131754:ERROR:process_info

526