2012-09-07 15 views
10

Istnieje wiele pytań na temat konwersji łańcuchów do wartości wyliczeniowej. Ogólnie rzecz biorąc, odpowiedź wyglądał odpowiedzi na this question:Dlaczego Enum.Parse() zwraca obiekt?

StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true); 

Mimo, że jest to całkowicie uzasadnione odpowiedź, można napisać metodę, aby uprościć połączenie, to nie jest odpowiedź na pytanie dlaczego Enum. Funkcja Parse() zwraca wartość object zamiast odpowiedniej wartości wyliczenia. Dlaczego muszę go przesłać na numer StatusEnum?


Edit:

Zasadniczo chodzi o to, dlaczego jest funkcją jak to nie część klasy Enum?

public static T Parse<T>(string value) where T: struct 
    { 
     return (T)Enum.Parse(typeof (T), value); 
    } 

Ta funkcja działa doskonale, działa dokładnie tak, jak można się spodziewać. StatusEnum e = Enum.Parse<StatusEnum>("Active");.

+1

@ SpYk3HH - Enums nie * ma * wartości. Są * wartościami *. Są to wartości, które zwykle mają przeciążenie dla '.ToString()', ale nadal są wartościami. – Bobson

+2

.NET 4.0+ ma ['Enum.TryParse '] (http://msdn.microsoft.com/en-us/library/dd783499 (v = vs.100)) –

+0

@ SpYk3HH wartością typu wyliczeniowego jest pewna liczba całkowita, która może być związana z jednym z pól typu wyliczeniowego. Wielkość liczby całkowitej może być różna. Parse pobiera ciąg znaków i zwraca instancję pudełkową typu wyliczeniowego. To może być rozpakowane lub nie. Twoje ostatnie zdanie również nie ma sensu. String i Boolean mają również właściwości i metody, na których można pracować. – phoog

Odpowiedz

10

Czyni to dlatego

  1. on poprzedzał rodzajowych i (nawet gdyby nie :)
  2. Generic ograniczenia nie mogą być teksty stałe (w językach .NET głównego nurtu)

Jako taki, Object jest jedynym typem, który zawsze będzie działał dla każdego typu enum.

Dzięki zwracaniu obiektu API jest co najmniej funkcjonalny, nawet jeśli wymagana jest rzutowanie.

+1

Chociaż nie możesz powiedzieć "where t: Enum", możesz powiedzieć 'where t: struct' i przynajmniej wyeliminować typy referencyjne lub nie wprowadzać ograniczeń i unikać rzutowania/typeof. – Guvante

+0

Fakt, że poprzednio generics nie jest wytworem. Byłoby niezłamującą się zmianą, aby dodać funkcję, którą edytowałem wyżej, jako przeciążenie starego stylu 'Enum.Parse()'. – Bobson

+0

@Reed - Pomyśl o tym, według twojej logiki, Enum.TryParse () również nie powinno istnieć, ale tak. – Bobson

1

Rzeczywisty typ obiektu to rzeczywiście StatusEnum. Kompilator i kod, pisząc Enum.Parse, nie mają pojęcia, czym będzie ten obiekt środowiska wykonawczego w chwili pisania tej metody. Nie będzie wiadomo, dopóki metoda nie zostanie wywołana.

3

TryParse ma jednak wspierać parametr typu:

Enum.TryParse<FooEnum>(name, true, out ret);

Dlatego też, jeśli określić wartość z ret jak FooEnum ret;, nie trzeba będzie oddać go do FooEnum później; będzie to właściwy typ od razu.

+0

To prawda, ale teraz potrzebujesz dwóch linii kodu. Prawdopodobnie trzy. Jeden do zadeklarowania 'ret', ten i jeden do użycia go, którego inaczej byś nie potrzebował. Podnosząc w ten sposób kwestię, dlaczego istnieje ogólna forma 'TryParse()', a nie generyczna forma 'Parse()'. – Bobson

+0

To jest prawdopodobnie przeoczone. Można jednak całkiem łatwo stworzyć własne ogólne przeciążenie jako metodę rozszerzenia. – aevitas

+0

W rzeczywistości nie można. Nie można rozszerzyć 'Enum', ponieważ jest to klasa statyczna. Tak więc nazywałbyś 'EnumExtensions.Parse' (lub cokolwiek nazwałeś twoją klasą) i nie byłoby żadnej korzyści z bycia metodą rozszerzenia. – Bobson

Powiązane problemy