Wyszukaj ciąg w Enum i zwróć Enum


163

Mam wyliczenie:

public enum MyColours
{
    Red,
    Green,
    Blue,
    Yellow,
    Fuchsia,
    Aqua,
    Orange
}

i mam ciąg:

string colour = "Red";

Chcę móc wrócić:

MyColours.Red

z:

public MyColours GetColour(string colour)

Jak dotąd mam:

public MyColours GetColours(string colour)
{
    string[] colours = Enum.GetNames(typeof(MyColours));
    int[]    values  = Enum.GetValues(typeof(MyColours));
    int i;
    for(int i = 0; i < colours.Length; i++)
    {
        if(colour.Equals(colours[i], StringComparison.Ordinal)
            break;
    }
    int value = values[i];
    // I know all the information about the matched enumeration
    // but how do i convert this information into returning a
    // MyColour enumeration?
}

Jak widać, trochę utknąłem. Czy mimo to można wybrać moduł wyliczający według wartości. Coś jak:

MyColour(2) 

spowoduje

MyColour.Green


4
@nawfal, nie znalazłem tego, kiedy pytałem o to wiele lat temu. Głosowałem za zamknięciem jako duplikat.
Matt Clarkson,

Odpowiedzi:


381

sprawdź System.Enum.Parse:


enum Colors {Red, Green, Blue}

// your code:
Colors color = (Colors)System.Enum.Parse(typeof(Colors), "Green");


72
Nie zapominaj, że możesz zignorować rozróżnianie wielkości liter, przekazując trzeci opcjonalny parametr jako „prawda”
Aerophilic

Dokładnie to, czego szukałem! Twoje zdrowie !
Zame

11
@ user1531040 Właściwie istnieje Enum.TryParse.
DarLom

Zwróć uwagę, że analiza wyliczenia zawsze kończy się sukcesem, jeśli dane wejściowe są numeryczne; po prostu zwraca przeanalizowaną liczbę, która następnie jest rzutowana na typ wyliczenia. Więc jeśli chcesz sprawdzić, czy dane wejściowe użytkownika są poprawnymi wyliczeniami, czy czymś innym, powinieneś najpierw sprawdzić zawartość liczbową. Ponieważ zwraca prawidłowe wyliczenie, ale z wartością, która może w ogóle nie istnieć w zdefiniowanych nazwach wyliczeń, możesz napotkać naprawdę dziwne problemy.
Nyerguds

19

Możesz rzutować int na wyliczenie

(MyColour)2

Istnieje również opcja Enum.Parse

(MyColour)Enum.Parse(typeof(MyColour), "Red")

11

Biorąc pod uwagę najnowsze i największe zmiany w .NET (+ Core) i C # 7, oto najlepsze rozwiązanie:

var ignoreCase = true;
Enum.TryParse("red", ignoreCase , out MyColours colour);

zmienną koloru można używać w zakresie Enum.TryParse



2

Oznaczyłem odpowiedź OregonGhost +1, a następnie spróbowałem użyć iteracji i zdałem sobie sprawę, że to nie jest w porządku, ponieważ Enum.GetNames zwraca ciągi. Chcesz Enum.GetValues:

public MyColours GetColours(string colour)
{  
   foreach (MyColours mc in Enum.GetValues(typeof(MyColours))) 
   if (mc.ToString() == surveySystem) 
      return mc;

   return MyColors.Default;
}

1

Możesz użyć, Enum.Parseaby uzyskać wartość wyliczenia z nazwy. Możesz iterować po wszystkich wartościach za pomocą Enum.GetNamesi możesz po prostu rzutować int na wyliczenie, aby uzyskać wartość wyliczenia z wartości int.

Na przykład tak:

public MyColours GetColours(string colour)
{
    foreach (MyColours mc in Enum.GetNames(typeof(MyColours))) {
        if (mc.ToString().Contains(colour)) {
            return mc;
        }
    }
    return MyColours.Red; // Default value
}

lub:

public MyColours GetColours(string colour)
{
    return (MyColours)Enum.Parse(typeof(MyColours), colour, true); // true = ignoreCase
}

Ten ostatni wyrzuci ArgumentException, jeśli wartość nie zostanie znaleziona, możesz chcieć przechwycić ją wewnątrz funkcji i zwrócić wartość domyślną.


UWAGA: Powinno to być oczywiście Enum.GetValues, jak pokazano w odpowiedzi Colina.
OregonGhost,

1
var color =  Enum.Parse<Colors>("Green");

To się nawet nie kompiluje. Nie ma Parsemetody ogólnej .
João Menighin

Skompilował się i działał dla mnie. Może to zależy od używanej wersji? Używam .NET core 3.1
Vinni

0

Jak wspomniano w poprzednich odpowiedziach, można rzutować bezpośrednio na podstawowy typ danych (int -> typ wyliczenia) lub analizować (ciąg -> typ wyliczenia).

ale uważaj - nie ma .TryParse dla wyliczeń, więc będziesz potrzebować bloku try / catch wokół parsowania, aby złapać błędy.


3
Nie było, zanim zadano to pytanie, ale teraz jest od .NET 4! msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx . Byłoby to coś w rodzaju Enum.TryParse <MyColour> ("Red", kolor out)
WienerDog

0
class EnumStringToInt // to search for a string in enum
{
    enum Numbers{one,two,hree};
    static void Main()
    {
        Numbers num = Numbers.one; // converting enum to string
        string str = num.ToString();
        //Console.WriteLine(str);
        string str1 = "four";
        string[] getnames = (string[])Enum.GetNames(typeof(Numbers));
        int[] getnum = (int[])Enum.GetValues(typeof(Numbers));
        try
        {
            for (int i = 0; i <= getnum.Length; i++)
            {
                if (str1.Equals(getnames[i]))
                {
                    Numbers num1 = (Numbers)Enum.Parse(typeof(Numbers), str1);
                    Console.WriteLine("string found:{0}", num1);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Value not found!", ex);
        }
    }
}

2
C # ma wbudowaną funkcjonalność do tego.
Artemix

jak to jest odpowiedź na pytanie? spójrz na inne odpowiedzi na znacznie łatwiejszy kod
Firo

0

Jedną rzeczą, która może ci się przydać (poza już poprawnymi / dobrymi odpowiedziami udzielonymi do tej pory) jest idea StringEnum podana tutaj

Dzięki temu możesz zdefiniować swoje wyliczenia jako klasy (przykłady znajdują się w vb.net):

<StringEnumRegisteredOnly (), DebuggerStepThrough (), ImmutableObject (True)> Public NotInheritable Class eAuthenticationMethod Inherits StringEnumBase (Of eAuthenticationMethod)

Private Sub New(ByVal StrValue As String)
  MyBase.New(StrValue)   
End Sub

< Description("Use User Password Authentication")> Public Shared ReadOnly UsernamePassword As New eAuthenticationMethod("UP")   

< Description("Use Windows Authentication")> Public Shared ReadOnly WindowsAuthentication As New eAuthenticationMethod("W")   

Koniec klasy

A teraz możesz użyć tej klasy tak, jak używałbyś wyliczenia: eAuthenticationMethod.WindowsAuthentication i byłoby to zasadniczo podobne do przypisania `` W '' wartości logicznej WindowsAuthentication (wewnątrz wyliczenia) i gdybyś miał wyświetlić tę wartość z właściwości window (lub coś innego, które używa właściwości System.ComponentModel.Description), otrzymasz „ Użyj uwierzytelniania systemu Windows ”.

Używam tego od dłuższego czasu i dzięki temu kod jest bardziej przejrzysty.


0
(MyColours)Enum.Parse(typeof(MyColours), "red", true); // MyColours.Red
(int)((MyColours)Enum.Parse(typeof(MyColours), "red", true)); // 0

-1

Możesz również zapoznać się z sugestiami zawartymi w tym poście na blogu: Mój nowy mały przyjaciel, Enum <T>

W poście opisano sposób tworzenia bardzo prostej ogólnej klasy pomocniczej, która pozwala uniknąć brzydkiej składni rzutowania nieodłącznie związanej z Enum.Parse- zamiast tego w kodzie piszesz coś takiego:

MyColours colour = Enum<MyColours>.Parse(stringValue); 

Lub sprawdź niektóre komentarze w tym samym poście, które mówią o użyciu metody rozszerzenia w celu osiągnięcia podobnych wyników.


Link do wpisu jest uszkodzony.
Machado,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.