2010-11-25 21 views
1

Je viens de rencontrer un comportement étrange lors de la définition d'une valeur d'enum par réflexion. Il semble que je suis en mesure de définir une valeur non valide pour le ENUM:Capable d'affecter une valeur Enum non valide via la réflexion

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

Maintenant, si j'appelle ceci:

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

La sortie est:

valeur est invalide : 1234 (1234)

Comment cela peut-il être? Je pense que l'une des natures mêmes des enums est leur ensemble de valeurs restreint!

Répondre

5

Les énumérations sont simplement des entiers (de n'importe quel type primitif entier, qui peuvent être spécifiés) avec certaines constantes nommées définies. Il n'y a pas besoin de réflexion pour attribuer une valeur qui n'a pas nommé constante:

enum MyEnum { 
    None, One, Two 
} 

MyEnum e = (MyEnum)100; 

Compile et fonctionne très bien. Notez que c'est également la raison de la méthode statique Enum.IsDefined(), qui vérifie si une valeur enum est une valeur définie.

+0

Bien sûr. Merci pour le conseil IsDefined() – Ive

0

Les énumérations sont très limitées, mais à la compilation. Voici l'inconvénient de la réflexion: vous perdez tous les contrôles à la compilation, fournis par le compilateur et exploitez les valeurs pour votre propre responsabilité.

+1

Ils sont même pas limités au moment de la compilation - vous pouvez écrire '(MyEnum) 1234' pour obtenir le même effet sans utiliser la réflexion. –

0

Vous ne même pas besoin de recourir à la réflexion:

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