Enum.IsDefined с помеченными перечислениями - PullRequest
8 голосов
/ 09 февраля 2011

В настоящее время я читаю книгу C # 4.0 в двух словах , которая, кстати, я считаю отличной книгой, которую даже опытные программисты могут использовать в качестве хорошего справочника.

Я оглядывался назад на главы об основах и наткнулся на хитрость, чтобы определить, определено ли определенное значение в Enum при использовании помеченных перечислений.В книге утверждается, что использование Enum.IsDefined не работает с помеченными перечислениями, и предлагается обходной путь, подобный этому:

static bool IsFlagDefined(Enum e)
{
    decimal d;
    return (!decimal.TryParse(e.ToString(), out d);
}

Это должно возвращать true, если определенное значение определено в перечислении, помеченном.

Может кто-нибудь объяснить мне, почему это работает?

Заранее спасибо:)

Ответы [ 2 ]

12 голосов
/ 09 февраля 2011

По сути, вызов ToString для любого значения enum типа, объявленного с атрибутом [Flags], вернет что-то подобное для любого определенного значения:

SomeValue, SomeOtherValue

С другой стороны, если значение не , определенное в типе enum, то ToString просто создаст строковое представление значения integer этого значения, например :

5

Так что это означает, что если вы можете проанализировать вывод ToString как число (не уверен, почему автор выбрал decimal), он не определен в типе.

Вот иллюстрация:

[Flags]
enum SomeEnum
{
    SomeValue = 1,
    SomeOtherValue = 2,
    SomeFinalValue = 4
}

public class Program
{
    public static void Main()
    {
        // This is defined.
        SomeEnum x = SomeEnum.SomeOtherValue | SomeEnum.SomeFinalValue;

        Console.WriteLine(x);

        // This is not (no bitwise combination of 1, 2, and 4 will produce 8).
        x = (SomeEnum)8;

        Console.WriteLine(x);
    }
}

Вывод вышеуказанной программы:

SomeOtherValue, SomeFinalValue
8

Итак, вы можете увидеть, как работает предложенный метод.

0 голосов
/ 09 февраля 2011

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

Но почему ваш код разбирается как десятичный, мне не совсем понятно. Но, вероятно, целочисленные типы не будут работать для enum с, основанных на Int64 и UInt64.

...