Нужно ли перечислять .net FlagsAttribute перечисления вручную?

StackOverflow https://stackoverflow.com/questions/1607442

Вопрос

Чтобы разрешить разные параметры форматирования в методе, отображающем новость, я создал перечисление, которое можно передать, чтобы указать способ его отображения.

[Flags]
private enum NewsStyle
{
    Thumbnail = 0,
    Date = 1,
    Text = 2,
    Link = 4,
    All = 8
}

string FormatNews( DataRow news, NewsStyle style )
{
    StringBuilder HTML = new StringBuilder();

    // Should the link be shown
    if ( ((newsStyle & NewsStyle.All) == NewsStyle.All || (newsStyle & NewsStyle.Link) == NewsStyle.Link))
    {
                HTML.AppendFormat("<a style=\"text-decoration:none; color: rgb(66, 110, 171);\" href=\"ViewStory.aspx?nsid={0}\">",
                                  UrlEncode(newsStory["NewsStoryID"].ToString()));
    }

    // Etc etc...
}

// So to call the method...
Response.Write( FormatNews( news, NewsStyle.Date | NewsStyle.Text ) );

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

Я всегда следовал правилу, разрешающему .net обрабатывать присвоение значений перечислениям - это исключение geniuine?

Это было полезно?

Решение

Да, это подлинное исключение. Перечисления по умолчанию назначаются значения от 0 и далее, каждое на 1 больше, чем предыдущее значение, независимо от каких-либо FlagsAttribute . (Конечно, есть более сложные правила, когда вы указываете некоторые значения вручную & # 8211; см. Документы MSDN )

Хотя в некоторой степени имеет смысл, чтобы перечисление флагов автоматически получало значения в степени двух, я вижу причины, по которым, вероятно, лучше этого не делать:

Совершенно разумно иметь такое перечисление:

[Flags]
enum Foo
{
    None,
    Bar,
    Baz, 
    BarAndBaz
} 

Это, конечно, требует, чтобы значения были 0, 1, 2 и 3, чтобы быть разумными.

Было бы довольно нелогично допустить, чтобы присутствие простого атрибута изменило весь смысл фрагмента кода C #. Рассмотрим мой пример Foo . Следует ли разрешить удаление атрибута Flags , чтобы нарушить код путем бесшумного изменения значений перечислителя?

Другие советы

Да, вы должны указать значения в Enum, чтобы добавленные значения флага работали правильно (чтобы можно было комбинировать два флага enum и не конфликтовать это значение с другим указанным флагом). Вам не нужно указывать значения, чтобы получить его для компиляции, но, скорее всего, результат будет не тот, который вы ищете.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top