2010-11-25 197 views
1

我剛剛遇到一些奇怪的行爲,當通過反射設置一個枚舉的值。這似乎是我能爲枚舉設置無效值:現在能夠通過反射分配一個無效的枚舉值

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)

這是怎麼回事?我雖然枚舉的本質之一是它們的限制值集合!

回答

5

枚舉只是整數(可以指定任何整數基本類型,可以指定)與一些定義的命名常量。不需要反射來分配一個沒有命名常量的值:

enum MyEnum { 
    None, One, Two 
} 

MyEnum e = (MyEnum)100; 

編譯和工作得很好。請注意,這也是Enum.IsDefined()靜態方法的原因,該方法檢查枚舉值是否爲定義的值。

+0

當然。感謝IsDefined()提示 – Ive 2010-11-25 11:46:38

0

枚舉實際上是限定值的,但是在編譯時。這是反射的缺點:你放棄編譯器提供的所有編譯時檢查,併爲自己的責任操作值。

+1

他們不是在編譯時甚至限制 - 你可以寫'(MyEnum)1234`得到相同的效果,而不使用反射。 – 2010-11-25 11:42:41

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