2010-07-28 3 views
5

J'essaie de renvoyer une valeur d'énumération fortement typée à partir d'une chaîne. Je suis sûr qu'il y a une meilleure façon de le faire. Cela semble juste beaucoup trop de code pour une chose simple comme ceci:Comment renvoyer une valeur Enum à partir d'une chaîne?

public static DeviceType DefaultDeviceType 
    { 
     get 
     { 
      var deviceTypeString = GetSetting("DefaultDeviceType"); 
      if (deviceTypeString.Equals(DeviceType.IPhone.ToString())) 
       return DeviceType.IPhone; 
      if (deviceTypeString.Equals(DeviceType.Android.ToString())) 
       return DeviceType.Android; 
      if (deviceTypeString.Equals(DeviceType.BlackBerry.ToString())) 
       return DeviceType.BlackBerry; 
      if (deviceTypeString.Equals(DeviceType.Other.ToString())) 
       return DeviceType.Other; 
      return DeviceType.IPhone; // If no default is provided, use this default. 
     } 
    } 

Idées? Sur la base des commentaires que j'ai reçus de la communauté, j'ai décidé d'utiliser une extension de méthode qui convertit une chaîne en une énumération. Il prend un paramètre (la valeur d'énumération par défaut). Cette valeur par défaut fournit également le type, de sorte que le générique peut être déduit et n'a pas besoin d'être spécifié explicitement en utilisant <>. La méthode est maintenant raccourcie à ceci:

public static DeviceType DefaultDeviceType 
    { 
     get 
     { 
      return GetSetting("DefaultDeviceType").ToEnum(DeviceType.IPhone); 
     } 
    } 

Solution très cool qui peut être réutilisée dans le futur.

Répondre

13

Si vous traitez avec une entrée d'utilisateur (non fiable), j'aime utiliser une méthode d'extension qui permet une valeur par défaut. Essaye le.

public static TResult ParseEnum<TResult>(this string value, TResult defaultValue) 
    { 
     try 
     { 
      return (TResult)Enum.Parse(typeof(TResult), value, true); 
     } 
     catch (ArgumentException) 
     { 
      return defaultValue; 
     } 
    } 
+0

Très cool, j'aime la possibilité de fournir un défaut - je vais probablement finir par l'utiliser. Merci. –

+3

C'est une bonne approche. En fonction de votre version de .NET, le plus récent Enum.TryParse vous permet de conserver cette même méthode tout en vous débarrassant du bloc try. – TechNeilogy

+0

@TechNeilogy J'utilise .net 3.5, n'a pas vu la méthode TryParse - qui doit être nouvelle avec 4.0? –

15

Utilisation Enum.Parse():

var deviceTypeString = GetSetting("DefaultDeviceType"); 
return (DeviceType)Enum.Parse(typeof(DeviceType), deviceTypeString); 

Si l'entrée est peu fiable, vous devez prendre soin, parce que vous obtiendrez un ArgumentException si la valeur ne peut être interprétée comme l'une des valeurs de l'ENUM.

Il existe également une surcharge de Parse() qui vous permet d'ignorer le cas lors de cette conversion, si nécessaire.

+0

Nice, qui est bien meilleur. Merci! –

1

j'ai écrit cette méthode d'extension une fois pour convertir à tout tout type enum de chaîne, de cette façon vous n'avez pas à écrire le code de conversion encore et encore:

public static class StringExtensions 
    { 

    public static T ConvertToEnum<T>(this string value) 
    { 
     //Guard condition to not allow this to be used with any other type than an Enum 
     if (typeof(T).BaseType != typeof(Enum)) 
     { 
      throw new InvalidCastException(string.Format("ConvertToEnum does not support converting to type of [{0}]", typeof(T))); 
     } 


     if (Enum.IsDefined(typeof(T), value) == false) 
     { 
      //you can throw an exception if the string does not exist in the enum 
      throw new InvalidCastException(); 

      //If you prefer to return the first available enum as the default value then do this 
      Enum.GetNames(typeof (T))[0].ConvertToEnum<T>(); //Note: I haven't tested this 
     } 
     return (T)Enum.Parse(typeof(T), value); 
    } 
} 

Pour utiliser réellement il vous pouvez le faire:

//This is a enumeration for testing 
enum MyEnumType 
{ 
    ENUM1, 
    ENUM2 
} 

//How to cast 
var myEnum = "ENUM2".ConvertToEnum<MyEnumType>(); 

MyEnum à ce point doit être égal ENUM2

+0

C'est lisse! La seule chose que je n'ai pas vu est comment gérer le cas quand une analyse échoue, quelle est la valeur par défaut? Peut-être que je peux ajouter une surcharge pour passer la valeur par défaut dans la méthode d'extension. –

+0

Je pense que si j'expose une méthode qui ne prend pas par défaut, alors je peux juste utiliser la première valeur d'énumération (par défaut). Savez-vous comment obtenir la première valeur d'énumération, tout en utilisant un générique comme dans le code ci-dessus? –

+0

@Paul merci, et bien si l'analyse échoue, personnellement, je voudrais savoir à ce sujet, et je lance une exception. Je ne voudrais pas renvoyer une valeur par défaut car cela pourrait provoquer des erreurs de logique, quand je suppose que l'analyse fonctionne, mais elle échoue et ne fait que renvoyer une valeur par défaut. – 7wp

Questions connexes