能够通过反射分配无效的枚举值

时间:2010-11-25 11:35:31

标签: c# reflection enums

通过反射设置枚举值时,我遇到了一些奇怪的行为。好像我能够为枚举设置一个无效的值:

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);
    }
}

现在,如果我这样称呼:

        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);
        }

输出结果为:

  

价值无效:1234(1234)

这怎么可能?我虽然枚举的本质之一就是限制价值!

3 个答案:

答案 0 :(得分:5)

枚举只是整数(任何整数基本类型,可以指定)和一些已定义的命名常量。不需要反射来分配没有命名常量的值:

enum MyEnum {
    None, One, Two
}

MyEnum e = (MyEnum)100;

编译并正常工作。请注意,这也是Enum.IsDefined()静态方法的原因,该方法检查枚举值是否为定义值。

答案 1 :(得分:0)

枚举是非常严格的值集,但是在编译时。这是反射的缺点:您放弃了编译器提供的所有编译时检查,并为自己的职责操作值。

答案 2 :(得分:0)

你甚至不需要求助于反思:

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);
}