2010-11-25 2 views
1

Я просто столкнулся с каким-то странным поведением при настройке значения enum через отражение. Похоже, что я в состоянии установить недопустимое значение для перечисления:Возможность присвоить неверное значение 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); 
    } 
} 

Теперь, если я называю это:

 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

Enums - это целые числа (любого целочисленного примитивного типа, который может быть указан) с некоторыми определенными константами. Нет необходимости в отражении для присвоения значения, которое не имеет постоянной имени:

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); 
} 
Смежные вопросы