I've just come across some strange behavior when setting an enum's value via reflection. It seems like I'm able to set an invalid value for the enum:
class EnumReflector
{
public enum MyEnum
{
Option1 = 0,
Option2,
Option3
}
public MyEnum TheEnum { get; set; }
public void Test()
{
PropertyInfo pi = this.GetType().GetProperty("TheEnum");
string badValue = "1234";
object propertyValue = Enum.Parse(pi.PropertyType, badValue, true);
pi.SetValue(this, propertyValue, null);
}
}
Now, if I call this:
EnumReflector e = new EnumReflector();
e.Test();
if (e.TheEnum == EnumReflector.MyEnum.Option1 ||
e.TheEnum == EnumReflector.MyEnum.Option2 ||
e.TheEnum == EnumReflector.MyEnum.Option3)
{
Console.WriteLine("Value is valid");
}
else
{
Console.WriteLine("Value is invalid: {0} ({1})", e.TheEnum.ToString(), (int)e.TheEnum);
}
The output is:
开发者_如何学编程Value is invalid: 1234 (1234)
How can this be? I though one of the very natures of enums is their restricted value-set!
Enums are just integers (of any integer primitive type, which can be specified) with some defined named constants. There is no need for reflection to assign a value which has no named constant:
enum MyEnum {
None, One, Two
}
MyEnum e = (MyEnum)100;
Compiles and works just fine. Note that this is also the reason for the Enum.IsDefined()
static method, which checks if an enum value is a defined value.
Enums are really stricted value-set, but at the compile time. Here is the disadvantage of the reflection: you loose all the compile-time checks, provided by the compiler and operate the values for own responsibility.
You don't even need to resort to reflection:
EnumReflector e = new EnumReflector();
e.TheEnum = (EnumReflector.MyEnum)1234;
if (e.TheEnum == EnumReflector.MyEnum.Option1 ||
e.TheEnum == EnumReflector.MyEnum.Option2 ||
e.TheEnum == EnumReflector.MyEnum.Option3)
{
Console.WriteLine("Value is valid");
}
else
{
Console.WriteLine("Value is invalid: {0} ({1})",
e.TheEnum.ToString(), (int)e.TheEnum);
}
精彩评论