Что действительно делает атрибут [Flags]? - PullRequest
28 голосов
/ 05 мая 2011

Что в действительности применяет [Flags]?

Я знаю, что это изменяет поведение Enum.ToString, но делает ли оно что-нибудь еще?(Например, другое поведение компилятора или среды выполнения и т. д.)для использования в качестве побитовых флагов, и что более логично применять его к битовым флагам.Однако я спрашивал больше о конкретных изменениях поведения, а не об общих методах программирования.

Ответы [ 6 ]

28 голосов
/ 05 мая 2011

Из статьи MSDN :

Интересно отметить, что когда Флаги указаны, Разбор и Формат методы обладают расширенными возможностями.

Аналогично, метод Parse может успешно разобрать запятую Строка, как показано на рисунке правильное числовое значение.

16 голосов
/ 05 мая 2011

См. Пост Дэвида М. Кина здесь . Похоже, это проблема языкового взаимодействия:

Хотя C # позволяет пользователям выполнять битовые операции над перечислениями без FlagsAttribute, Visual Basic этого не делает. Так что если вы выставляете типы на другие языки, то хорошая пометка перечислений с FlagsAttribute - хорошая идея; это также дает понять, что члены перечисления предназначены для совместного использования.

Привет

David

6 голосов
/ 05 мая 2011

Вот список конкретных поведенческих различий:

  • Установка перечисления с [flags] на None удаляет все флаги.
  • Метод HasFlags работает только при наличии этого атрибута.
  • Как сказал Девио, это меняет возможности методов Parse и Format. Он связался с этой статьей . По-видимому, это также влияет на то, что показано в отладчиках.
  • Я думал, что [флаги], вероятно, оказали влияние на генерацию кода в веб-сервисах, но похоже, что это не так.
  • Для ясности, побитовые операции разрешены для любого перечисления с или без [flags]. Но его использование - лучшая практика.

Подробнее: http://msdn.microsoft.com/en-us/library/ms229062.aspx

5 голосов
/ 05 мая 2011

Если вы спросите, что он делает под капотом, насколько я знаю, он меняет метод ToString (), ничего другого.

В .Net 4 у вас есть HasFlags -метод для проверки конкретных флагов.Если я правильно интерпретирую msdn, вы должны использовать атрибут flags для использования этого метода.Но я не пробовал.

1 голос
/ 05 мая 2011

На практике одно из применений, которые я использую, - это указание нескольких статусов.Это упрощение некоторого кода, который оценивает результаты теста.Тест может быть в порядке, или он может иметь несколько причин, чтобы не быть в порядке.Преимущество, которое это дает, состоит в том, что у меня есть один метод, который оценивает тесты «Ok-ness», и этот метод способен указывать все возможные условия отказа с одним возвратом.Возможно, это не лучший дизайн, но в этом случае он работает.

[Flags]
public enum ResultStatusEnum
{
    Ok = 0x1,
    SampleInvalid = 0x2,
    DirectionInvalid = 0x4,
    TestIsNotValid = 0x8
}

Вы устанавливаете его так:

ResultStatusEnum res = ResultStatusEnum.SampleInvalid | ResultStatusEnum.DirectionInvalid;

Недостатком является то, что проверка значений перечисления становится громоздкой,Это не будет (обязательно) работать:

res == ResultStatusEnum.Ok

Вы должны сделать это, чтобы проверить:

ResultStatusEnum.SampleInvalid == (res & ResultStatusEnum.SampleInvalid)

В этом случае нелогично иметь ResultStatusEnum.Ok & ResultStatusEnum.SampleInvalid, но я простоубедитесь, что это не тот случай, когда я использую перечисление.

0 голосов
/ 21 августа 2018

Flags дает возможность использовать enum для нескольких значений.

Рассмотрим ситуацию, когда вы хотите использовать флажки для другой ситуации, но не хотите создавать разные столбцы в базе данных. Если у вас есть 20 флажков, вам нужно будет создать 20 столбцов в базе данных с помощью bool. Но с флагами вы можете создать один столбец и использовать это значение для хранения в столбце. Запустите этот пример в консоли, чтобы лучше понять его.

class Program
{
    static void Main(string[] args)
    {
        //Set the features that you require for car. Consider it as checked in the UI.
        CarFeatures carFeatures = CarFeatures.AC | CarFeatures.Autopilot| CarFeatures.Sunroof;

        //Do the backend logic
        if (carFeatures.HasFlag(CarFeatures.Autopilot))
        {
            //Show Autopilot cars
        }
        //See the what carfeatures are required
        Console.WriteLine(carFeatures);
        //See the integer value of the carfeatures
        Console.WriteLine((int)carFeatures);
        Console.ReadLine();
    }
}

[Flags]
public enum CarFeatures
{
    AC=1,
    HeatedSeats= 2,
    Sunroof= 4,
    Autopilot= 8,
}

Различная комбинация всегда дает вам уникальный номер, который c # отслеживает, чтобы найти то, что все помечены.

...