2010-07-28 18 views
5

Sto cercando di restituire un valore Enumerazione fortemente tipizzato da una stringa. Sono sicuro che c'è un modo migliore per farlo. Questo sembra un po 'troppo codice per una cosa semplice come questa:Come restituire un valore Enum da una stringa?

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. 
     } 
    } 

Idee?

Sulla base del feedback ricevuto dalla comunità, ho deciso di utilizzare un'estensione di metodo che converte una stringa in un'enumerazione. Prende un parametro (il valore di enumerazione predefinito). Questo valore predefinito fornisce anche il tipo, quindi il generico può essere dedotto e non è necessario specificarlo esplicitamente utilizzando <>. Il metodo è ora ridotta a questo:

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

soluzione molto freddo che può essere riutilizzato in futuro.

risposta

13

Se si ha a che fare con l'input dell'utente (inaffidabile), mi piace utilizzare un metodo di estensione che consenta un valore predefinito. Provalo.

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

Very Cool, mi piace la possibilità di fornire un valore predefinito - probabilmente finirò per usarlo. Grazie. –

+3

Questo è un buon approccio. A seconda della versione di .NET, il più recente Enum.TryParse consente di mantenere lo stesso metodo eliminando il blocco try. – TechNeilogy

+0

@TechNeilogy Sto usando .net 3.5, non ho visto il metodo TryParse - che deve essere nuovo con 4.0? –

15

Uso Enum.Parse():

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

Se l'ingresso è inaffidabile, si dovrebbe prendere cura, perché si otterrà un ArgumentException se il valore non può essere interpretato come uno dei valori della enum.

C'è anche un sovraccarico di Parse() che consente di ignorare il caso quando si effettua questa conversione, se necessario.

+0

Nizza, questo è il modo migliore. Grazie! –

1

Ho scritto questo metodo di estensione, una volta per convertire qualsiasi qualsiasi tipo enum da stringa, in questo modo non c'è bisogno di scrivere il codice di conversione più e più volte:

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

Per utilizzare effettivamente che si può fare questo:

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

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

MyEnum a questo punto deve essere uguale ENUM2

+0

Questo è perfetto! L'unica cosa che non ho visto è come gestire il caso quando un parse fallisce, quale default dovrebbe essere usato? Forse posso aggiungere un sovraccarico per passare il valore predefinito nel metodo di estensione. –

+0

Sto pensando se esporre un metodo che non accetta un valore predefinito, quindi posso semplicemente usare il primo valore di enumerazione (per un valore predefinito). Sai come ottenere il primo valore di enumerazione, mentre usi un generico come nel codice sopra? –

+0

@Paul grazie, beh, se l'analisi fallisce, personalmente vorrei saperlo e lancio un'eccezione. Non vorrei restituire un valore predefinito perché ciò potrebbe causare alcuni errori logici, quando presumo che l'analisi funzioni, ma in realtà non funziona e in realtà restituisco solo un valore predefinito. – 7wp

Problemi correlati