V3059. Consider adding '[Flags]' attribute to the enum.
Анализатор посчитал подозрительным перечисление, элементы которого участвуют в битовых операциях или имеют значения, равные степеням 2. Но при этом само перечисление не отмечено атрибутом [Flags].
Если выполняется одно из этих условий, то для использования перечислений как битовых флагов, необходимо отметить перечисление атрибутом [Flags], что даст ряд преимуществ при работе с этим перечислением в коде.
Для того, чтобы лучше понять, как изменяет поведение программы применение атрибута [Flags] к перечислимому типу, рассмотрим несколько примеров:
enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
// en1: 5
var en1 = (Suits.Spades | Suits.Diamonds);
Без атрибута [Flags] результатом применения битовой операции OR для членов со значениями '1' и '4' будет значение '5'.
Поведение меняется, если для перечисления задан атрибут [Flags]:
[Flags]
enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
// en2: SuitsFlags.Spades | SuitsFlags.Diamonds;
var en2 = (SuitsFlags.Spades | SuitsFlags.Diamonds);
В таком случае результат операции OR рассматривается не как единственное целочисленное значение, а как набор битов, содержащих значения 'SuitsFlags.Spades' и 'SuitsFlags.Diamonds'.
Если у объектов 'en1' и 'en2' вызвать метод 'ToString', его результат также будет различаться. Данный метод попытается преобразовать числовое значение в символьный эквивалент, но у значения '5' нет символьного эквивалента. Однако обнаружив у типа атрибут [Flags], метод 'ToString' рассматривает числовое значение как набор битовых флагов. Следовательно, вызов метода 'ToString' для объектов 'en1' и 'en2' даст следующий вывод:
String str1 = en1.ToString(); // "5"
String str2 = en2.ToString(); // "SuitsFlags.Spades |
// SuitsFlags.Diamonds"
По аналогии работают и получения числовых значений из строки при использовании статических методов 'Parse' и 'TryParse' класса 'Enum'.
Дополнительным преимуществом использования [Flags] является упрощение процесса отладки. Значение переменной 'en2' будет отображаться как набор именованных констант, а не как просто число:
Дополнительная информация:
- What does the [Flags] Enum Attribute mean in C#?
- CLR via C#. Jeffrey Richter. Chapter 15 - Enumerated Types and Bit Flags.