Почему операторы << и >> не реализованы для перечислений флагов в C #? - PullRequest
1 голос
/ 17 октября 2011

Я хочу сделать что-то подобное, но не могу:

[Flags]
enum SomeEnum : int
{ 
 None = 0,
 A,
 B,
 C
}

SomeEnum en = SomeEnum.A;
en <<= 1; //Expect en == SomeEnum.B but I recieve an error here

Для чего это было сделано?

Ответы [ 3 ]

6 голосов
/ 17 октября 2011

Перечисления не являются битовыми полями сами по себе. Весь смысл перечислений состоит в том, чтобы абстрагироваться от любых базовых ценностей. Использование операторов сдвига подразумевает знание этих значений.

Однако, если вы действительно хотите сдвинуться, просто бросьте:

en = (SomeEnum)((int)en << 1);
2 голосов
/ 17 октября 2011

Перечисление [Flag] может содержать комбинацию флагов.Изменение комбинации редко приводит к разумному значению

SomeEnum en = SomeEnum.A | SomeEnum.B;
en <<= 1; //Expect what?

Вы можете привести к int и делать то, что вам нравится, если вы знаете, что делаете

ПРИМЕЧАНИЕ: если вы действительно хотитеиспользуйте SomeEnum без явного приведения, вы можете заключить его в тип, подобный Pseudo<SomeEnum>, который я определил здесь: Можно ли обернуть целое и назвать его целым числом?

Обратите внимание, что это действительно доказательство концепции, но вы можете увидеть, как это будет работать оттуда

0 голосов
/ 17 октября 2011

Я бы сказал, что это потому, что вы не можете применить оператор «<< =» к операндам типа «SomeEnum» и «int» ».Таким образом, вместо этого вы должны выполнить довольно менее элегантный </p>

var en = SomeEnum.A;

en = (SomeEnum)((int)en << 1);

, который явно выполняет преобразование типа или, если вы предпочитаете, можете подождать, пока <<= будет выполнен или неявное приведение Enum кОператор int для реализации, ни один из которых не представляется вероятным, это не то, что должно быть сделано случайно.

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

...