This question already has an answer here:
这个问题在这里已有答案:
- Why does casting int to invalid enum value NOT throw exception? 4 answers
- 为什么将int转换为无效的枚举值而不抛出异常? 4个答案
I was working on a web service method that will receive an array of ints as parameter, and then, inside the method, I converted the values in the array into enum values, and stored them in a enum list. However, when a value that's not in the enum is passed, it is added to the enum list with no problems. No InvalidCastException
, nothing. I made a test project that looks like this:
我正在研究一个Web服务方法,它将接收一个int数组作为参数,然后,在方法内部,我将数组中的值转换为枚举值,并将它们存储在枚举列表中。但是,当传递不在枚举中的值时,它将被添加到枚举列表中而没有任何问题。没有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
}
}
When I run it, the output is:
当我运行它时,输出是:
Value1
Value2
15
For my web service, I'll implement a validation, so this will never hapen at all. But... this is weird! Shouldn't the runtime throw a InvalidCastException
or ArgumentOutOfRangeException
, or something similar? Since I got a list of enums (and not int values), I want the values to be limitted to the values of the enum (that's what an enum is for).
对于我的Web服务,我将实现验证,因此这根本不会有任何问题。但是......这很奇怪!不应该运行时抛出InvalidCastException或ArgumentOutOfRangeException,或类似的东西?由于我得到了一个枚举列表(而不是int值),我希望将值限制为枚举值(这就是枚举的用途)。
Am I missing something? Is this a .NET bug, a C# bug or is there something I don't know with enums?
我错过了什么吗?这是一个.NET错误,一个C#错误还是存在一些我不知道的枚举?
5 个解决方案
#1
19
You can assign any value to an enum
that the underlying type allows. By default, the underlying type is int
, so you can assign any int
value to the enum
.
您可以将任何值分配给基础类型允许的枚举。默认情况下,基础类型为int,因此您可以将任何int值分配给枚举。
The main reason for this is because if you have a [Flags]
enumeration, you want to be able to assign composite values:
这样做的主要原因是,如果您有[Flags]枚举,您希望能够分配复合值:
[Flags]
public enum MyFlags
{
A = 1,
B = 2
}
MyFlags flags = (MyFlags)3; // Equivalent to setting A and B
Preferably you'd just use the enumeration values to do that, though:
但是,您最好只使用枚举值来执行此操作:
MyFlags flags = MyFlags.A | MyFlags.B; // Sets flags to 3
It's important to note, of course, that the [Flags]
attribute isn't required to enable this assignment. All enum
s have this property, by design.
当然,重要的是要注意,启用此分配不需要[Flags]属性。根据设计,所有的枚举都有这个属性。
As pointed out by a number of people, you can use Enum.IsDefined()
to determine if a particular value is valid for a given enum
. That should help with your validation.
正如许多人所指出的,您可以使用Enum.IsDefined()来确定特定值是否对给定的枚举有效。这应该有助于您的验证。
#2
5
Yes, there is no check for defined values when you convert to an enum value.
是的,转换为枚举值时,不会检查定义的值。
You can use the IsDefined
method to check if a specific value is defined:
您可以使用IsDefined方法检查是否定义了特定值:
if (Enum.IsDefined(typeof(TestValues), value)) ...
#3
1
You can always cast any int value to an enum based on int. This is by design, as the cast would be a lot slower if it had to check all legal values.
您始终可以基于int将任何int值转换为枚举。这是设计,因为如果必须检查所有合法值,演员会慢得多。
#4
1
You should read the following thread:
您应该阅读以下主题:
Why does Enum.Parse create undefined entries?
为什么Enum.Parse会创建未定义的条目?
In short, this is valid. If you want to check if the value is defined, use Enum.IsDefined
.
简而言之,这是有效的。如果要检查是否已定义值,请使用Enum.IsDefined。
#5
1
To determine if the specified int
is defined within the enum
you can use Enum.IsDefined.
要确定是否在枚举中定义了指定的int,可以使用Enum.IsDefined。
Enum.IsDefined(typeof(TestValues), 15);
#1
19
You can assign any value to an enum
that the underlying type allows. By default, the underlying type is int
, so you can assign any int
value to the enum
.
您可以将任何值分配给基础类型允许的枚举。默认情况下,基础类型为int,因此您可以将任何int值分配给枚举。
The main reason for this is because if you have a [Flags]
enumeration, you want to be able to assign composite values:
这样做的主要原因是,如果您有[Flags]枚举,您希望能够分配复合值:
[Flags]
public enum MyFlags
{
A = 1,
B = 2
}
MyFlags flags = (MyFlags)3; // Equivalent to setting A and B
Preferably you'd just use the enumeration values to do that, though:
但是,您最好只使用枚举值来执行此操作:
MyFlags flags = MyFlags.A | MyFlags.B; // Sets flags to 3
It's important to note, of course, that the [Flags]
attribute isn't required to enable this assignment. All enum
s have this property, by design.
当然,重要的是要注意,启用此分配不需要[Flags]属性。根据设计,所有的枚举都有这个属性。
As pointed out by a number of people, you can use Enum.IsDefined()
to determine if a particular value is valid for a given enum
. That should help with your validation.
正如许多人所指出的,您可以使用Enum.IsDefined()来确定特定值是否对给定的枚举有效。这应该有助于您的验证。
#2
5
Yes, there is no check for defined values when you convert to an enum value.
是的,转换为枚举值时,不会检查定义的值。
You can use the IsDefined
method to check if a specific value is defined:
您可以使用IsDefined方法检查是否定义了特定值:
if (Enum.IsDefined(typeof(TestValues), value)) ...
#3
1
You can always cast any int value to an enum based on int. This is by design, as the cast would be a lot slower if it had to check all legal values.
您始终可以基于int将任何int值转换为枚举。这是设计,因为如果必须检查所有合法值,演员会慢得多。
#4
1
You should read the following thread:
您应该阅读以下主题:
Why does Enum.Parse create undefined entries?
为什么Enum.Parse会创建未定义的条目?
In short, this is valid. If you want to check if the value is defined, use Enum.IsDefined
.
简而言之,这是有效的。如果要检查是否已定义值,请使用Enum.IsDefined。
#5
1
To determine if the specified int
is defined within the enum
you can use Enum.IsDefined.
要确定是否在枚举中定义了指定的int,可以使用Enum.IsDefined。
Enum.IsDefined(typeof(TestValues), 15);