Подтвердить что ты не робот

С# перечисляющий массив, принимающий неправильное значение

Я работал над методом веб-службы, который получит массив параметров ints в качестве параметра, а затем внутри метода я преобразовал значения в массиве в значения enum и сохранил их в списке перечислений. Однако, когда значение, не входящее в перечисление, передается, оно добавляется в список перечислений без проблем. Нет InvalidCastException, ничего. Я сделал тестовый проект, который выглядит так:

static class Program
{
    static void Main(string[] args)
    {
        List<TestValues> values = new List<TestValues>() {
            TestValues.Value1,
            TestValues.Value2,
            (TestValues)15
        };

        foreach (var val in values)
            Console.WriteLine(val);

        Console.Read();
    }

    enum TestValues
    { 
        Value1 = 2,
        Value2 = 4,
        Value3 = 8
    }
}

Когда я запускаю его, вывод:

Value1
Value2
15

Для моего веб-сервиса я буду выполнять проверку, так что это никогда не произойдет. Но... это странно! Должно ли время выполнения бросать InvalidCastException или ArgumentOutOfRangeException или что-то подобное? Поскольку у меня есть список перечислений (а не значений int), я хочу, чтобы значения были ограничены значениями перечисления (для чего используется перечисление).

Я что-то упустил? Это ошибка .NET, ошибка С# или есть что-то, чего я не знаю с перечислениями?

4b9b3361

Ответ 1

Вы можете назначить любое значение enum, которое допускает базовый тип. По умолчанию базовый тип int, поэтому вы можете назначить любое значение int для enum.

Основная причина этого в том, что если у вас есть перечисление [Flags], вы хотите иметь возможность назначать составные значения:

[Flags]
public enum MyFlags
{
    A = 1,
    B = 2
}

MyFlags flags = (MyFlags)3; // Equivalent to setting A and B

Предпочтительно для этого нужно использовать только значения перечисления:

MyFlags flags = MyFlags.A | MyFlags.B; // Sets flags to 3

Важно отметить, конечно, что атрибут [Flags] не требуется для включения этого назначения. Все enum имеют это свойство по своему усмотрению.

Как указано несколькими людьми, вы можете использовать Enum.IsDefined(), чтобы определить, действительно ли определенное значение для данного enum. Это должно помочь с вашей проверкой.

Ответ 2

Да, при преобразовании в значение перечисления нет проверки определенных значений.

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

if (Enum.IsDefined(typeof(TestValues), value)) ...

Ответ 3

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

Ответ 4

Чтобы определить, указан ли указанный int в enum, вы можете использовать Enum.IsDefined.

Enum.IsDefined(typeof(TestValues), 15);

Ответ 5

Вы должны прочитать следующий поток:

Почему Enum.Parse создает записи undefined?

Короче говоря, это действительно. Если вы хотите проверить, определено ли значение, используйте Enum.IsDefined.