2010-07-28 25 views
5

Bir dizeden çok yazılan bir Enumeration değeri döndürmeye çalışıyorum. Eminim bunu yapmanın daha iyi bir yolu vardır. Bu böyle basit bir şey için çok fazla kod gibi görünüyor:Bir dizeden Enum değeri nasıl döndürülür?

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

Fikirler?

Topluluktan aldığım geri bildirime dayanarak, bir dizeyi bir numaralandırmaya dönüştüren bir yöntem uzantısı kullanmaya karar verdim. Bir parametre alır (varsayılan numaralandırma değeri). Bu varsayılan da türünü sağlar, böylece jenerik çıkarılabilir ve <> kullanarak açıkça belirtilmesi gerekmez. Yöntem şu şekilde kısaltılmıştır: Gelecekte tekrar kullanılabilen çok hoş bir çözüm.

cevap

13

(güvenilmez) kullanıcı girdisiyle uğraşıyorsanız, varsayılan değere izin veren bir uzantı yöntemi kullanmak isterim. Denemek.

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

aslında kullanmak için:

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

Çok Cool, Bir varsayılan sunma yeteneğini beğeniyorum - muhtemelen bunu kullanarak bitireceğim. Teşekkürler. –

+3

Bu iyi bir yaklaşım. .NET sürümünüze bağlı olarak, yeni Enum.TryParse, try bloğundan kurtulurken aynı yöntemi saklamanıza izin verir. – TechNeilogy

+0

@TechNeilogy Kullanıyorum. Net 3.5, TryParse yöntemini görmedin - bu 4.0 ile yeni olmalı? –

15

Kullanım Enum.Parse(): Giriş güvenilmez

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

Eğer değer enum değerlerden biri olarak yorumlanamaz eğer bir ArgumentException alacak, çünkü, dikkat etmelisiniz.

Ayrıca, gerekiyorsa bu dönüşümü yaparken durumu görmezden gelmenizi sağlayan Parse() aşırı yüklenme de vardır.

+0

Güzel eşit olmalıdır, bu şekilde daha iyi. Teşekkürler! –

1

ipi herhangi herhangi enum tipine dönüştürmek için bir kez bu uzatma yöntemi, sen tekrar tekrar dönüşüm kodu yazmak zorunda değilsiniz bu şekilde yazdım Eğer bunu yapabilirsiniz: Bu noktada

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

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

MyEnum ENUM2

+0

Bu kaygan! Görmediğim tek şey, bir ayrıştırma başarısız olduğunda durumun nasıl ele alınacağı, hangi varsayılanın kullanılması gerektiği? Belki de varsayılan değeri uzatma yöntemine geçirmek için aşırı yük ekleyebilirim. –

+0

Bir varsayılan almayan bir yöntem ortaya çıkarırsam, ilk sayılandırma değerini (varsayılan olarak) kullanabilirim. Yukarıdaki kodda olduğu gibi jenerik kullanırken ilk numaralandırma değerini nasıl alacağınızı biliyor musunuz? –

+0

@Paul teşekkürler, eğer ayrıştırma başarısız olursa, kişisel olarak bunu bilmek isterdim ve bir istisna atarım. Varsayılan değere dönmek istemem çünkü parse çalıştığı varsayılırsa, bazı mantık hatalarına neden olabilir, ancak gerçekten başarısız oluyor ve gerçekten varsayılan bir değer döndürüyor. – 7wp

İlgili konular