С# перечисляющий массив, принимающий неправильное значение
Я работал над методом веб-службы, который получит массив параметров 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, ошибка С# или есть что-то, чего я не знаю с перечислениями?
Ответы
Ответ 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
.