2010-07-28 17 views
5

Próbuję zwrócić mocno wpisaną wartość wyliczenia z ciągu znaków. Jestem pewien, że jest lepszy sposób na zrobienie tego. Wydaje się, że to za dużo kodu na prostą rzecz:Jak zwrócić wartość wyliczenia z ciągu?

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

Pomysły?

Na podstawie opinii uzyskanych od społeczności, zdecydowałem się użyć rozszerzenia metody, które konwertuje ciąg do wyliczenia. Przyjmuje jeden parametr (domyślną wartość wyliczenia). Ta wartość domyślna zapewnia również typ, więc ogólne można wywnioskować i nie trzeba tego wyraźnie określać, używając <>. Metoda jest teraz skrócona do tego:

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

Bardzo fajne rozwiązanie, które można ponownie wykorzystać w przyszłości.

Odpowiedz

13

Jeśli masz do czynienia z niewiarygodnym wprowadzaniem danych przez użytkownika, chciałbym użyć metody rozszerzenia, która zezwala na wartość domyślną. Wypróbuj to.

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

Bardzo fajnie, podoba mi się możliwość ustawienia domyślnego - prawdopodobnie skończę z używaniem tego. Dzięki. –

+3

To jest dobre podejście. W zależności od wersji .NET, nowsza wersja Enum.TryParse pozwala zachować tę samą metodę, jednocześnie pozbywając się bloku try. – TechNeilogy

+0

@ TechNeilogy Używam .net 3.5, nie widziałem metody TryParse - która musi być nowa z wersją 4.0? –

15

Zastosowanie Enum.Parse():

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

Jeśli wejście jest zawodna, należy zadbać, bo dostaniesz ArgumentException jeżeli wartość nie może być interpretowane jako jedna z wartości wyliczenia.

Istnieje również przeciążenie Parse(), które pozwala w razie potrzeby zignorować wielkość liter podczas dokonywania konwersji.

+0

Nicea, to sposób lepszy. Dzięki! –

1

Napisałem tę metodę rozszerzenia raz do konwersji do dowolnego dowolnego typu enum z ciągiem, w ten sposób nie trzeba pisać kod konwersji w kółko:

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

faktycznie korzysta to można to zrobić:

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

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

myEnum w tym momencie powinna być równa ENUM2

+0

To jest zgrabne! Jedyne, czego nie widziałem, to jak obsłużyć przypadek, gdy parsowanie nie powiedzie się, jakie domyślne powinno być używane? Być może mogę dodać przeciążenie, aby przekazać wartość domyślną do metody rozszerzenia. –

+0

Zastanawiam się, czy mogę ujawnić metodę, która nie bierze domyślnie, to mogę po prostu użyć pierwszej wartości wyliczenia (dla domyślnego). Czy zdarza Ci się wiedzieć, jak uzyskać pierwszą wartość wyliczenia, podczas korzystania z generycznych jak w powyższym kodzie? –

+0

@Paul dziękuje, cóż, jeśli przetwarzanie nie powiedzie się, osobiście chciałbym o tym wiedzieć, a wyrzucam wyjątek. Nie chciałbym przywrócić wartości domyślnej, ponieważ mogłoby to spowodować błędy logiczne, gdy przyjmuję, że analizowanie działa, ale faktycznie kończy się niepowodzeniem i po prostu zwraca wartość domyślną. – 7wp

Powiązane problemy