Suchen Sie in Enum nach einer Zeichenfolge und geben Sie die Aufzählung zurück

163

Ich habe eine Aufzählung:

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

und ich habe eine Zeichenfolge:

string colour = "Red";

Ich möchte zurückkehren können:

MyColours.Red

von:

public MyColours GetColour(string colour)

Bisher habe ich:

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

Wie Sie sehen können, stecke ich ein bisschen fest. Gibt es sowieso einen Enumerator nach Wert auszuwählen. Etwas wie:

MyColour(2) 

würde dazu führen

MyColour.Green
Matt Clarkson
quelle
4
@nawfal, habe das nicht gefunden, als ich das vor all den Jahren gefragt habe. Habe dafür gestimmt, als Duplikat zu schließen.
Matt Clarkson

Antworten:

381

check out System.Enum.Parse:


enum Colors {Red, Green, Blue}

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

JMarsch
quelle
72
Vergessen Sie nicht, dass Sie die Groß- und Kleinschreibung ignorieren können, indem Sie einen dritten optionalen Parameter als "wahr" übergeben
Aerophilic
Genau das, wonach ich gesucht habe! Prost !
Zame
11
@ user1531040 Eigentlich gibt es eine Enum.TryParse.
DarLom
Beachten Sie, dass das Parsen von Enums immer erfolgreich ist, wenn die Eingabe numerisch ist. Es wird nur die analysierte Nummer zurückgegeben, die dann in den Typ der Aufzählung umgewandelt wird. Wenn Sie also überprüfen möchten, ob eine Benutzereingabe eine gültige Aufzählung oder etwas anderes ist, sollten Sie zuerst nach numerischem Inhalt suchen. Da es eine gültige Aufzählung zurückgibt, die jedoch in den definierten Aufzählungsnamen möglicherweise überhaupt nicht vorhanden ist, können einige wirklich seltsame Probleme auftreten.
Nyerguds
19

Sie können das int in eine Aufzählung umwandeln

(MyColour)2

Es gibt auch die Option Enum.Parse

(MyColour)Enum.Parse(typeof(MyColour), "Red")
Guvante
quelle
11

Angesichts der neuesten und größten Änderungen an .NET (+ Core) und C # 7 ist hier die beste Lösung:

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

Die Farbvariable kann im Rahmen von Enum.TryParse verwendet werden

römisch
quelle
5

Alles was Sie brauchen ist Enum.Parse .

Bruno Brant
quelle
2

Ich habe die Antwort von OregonGhost mit +1 markiert, dann habe ich versucht, die Iteration zu verwenden, und festgestellt, dass sie nicht ganz richtig ist, da Enum.GetNames Zeichenfolgen zurückgibt. Sie möchten Enum.GetValues:

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

   return MyColors.Default;
}
Colin
quelle
1

Sie können verwenden Enum.Parse, um einen Aufzählungswert aus dem Namen zu erhalten. Sie können mit über alle Werte iterieren Enum.GetNamesund einfach ein int in eine Aufzählung umwandeln, um den Aufzählungswert aus dem int-Wert zu erhalten.

So zum Beispiel:

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
}

oder:

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

Letzteres löst eine ArgumentException aus, wenn der Wert nicht gefunden wird. Möglicherweise möchten Sie ihn in der Funktion abfangen und den Standardwert zurückgeben.

OregonGhost
quelle
HINWEIS: Es sollte natürlich Enum.GetValues ​​sein, wie in Colins Antwort gezeigt.
OregonGhost
0

Wie in den vorherigen Antworten erwähnt, können Sie direkt in den zugrunde liegenden Datentyp (int -> Aufzählungstyp) oder die Analyse (Zeichenfolge -> Aufzählungstyp) umwandeln.

Aber Vorsicht - es gibt kein .TryParse für Aufzählungen, daher benötigen Sie einen Try / Catch-Block um die Analyse, um Fehler abzufangen.

Addys
quelle
3
War nicht bevor diese Frage gestellt wurde, aber jetzt gibt es ab .NET 4! msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx . Es wäre so etwas wie Enum.TryParse <MyColour> ("Rot",
keine
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);
        }
    }
}
Raja
quelle
2
C # verfügt hierfür über eine integrierte Funktionalität.
Artemix
Wie ist das eine Antwort auf die Frage? Schauen Sie sich die anderen Antworten für viel einfacheren Code an
Firo
0

Eine Sache , die Sie nützlich sein könnte (neben den bereits gültigen / guten Antworten zur Verfügung gestellt , so weit) ist die StringEnum Idee zur Verfügung gestellt hier

Damit können Sie Ihre Aufzählungen als Klassen definieren (die Beispiele finden Sie in vb.net):

<StringEnumRegisteredOnly (), DebuggerStepThrough (), ImmutableObject (True)> Öffentliche nicht vererbbare Klasse eAuthenticationMethod erbt 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")   

Klasse beenden

Und jetzt können Sie diese Klasse wie eine Aufzählung verwenden: eAuthenticationMethod.WindowsAuthentication. Dies entspricht im Wesentlichen der Zuweisung des ' W ' zum logischen Wert von WindowsAuthentication (innerhalb der Aufzählung) und der Anzeige dieses Werts aus einer Eigenschaft Fenster (oder etwas anderes, das die System.ComponentModel.Description-Eigenschaft verwendet) würden Sie " Windows-Authentifizierung verwenden " erhalten.

Ich benutze dies schon seit langer Zeit und es macht den Code in seiner Absicht klarer.

Ando
quelle
0
(MyColours)Enum.Parse(typeof(MyColours), "red", true); // MyColours.Red
(int)((MyColours)Enum.Parse(typeof(MyColours), "red", true)); // 0
Sandeep Shekhawat
quelle
0
var color =  Enum.Parse<Colors>("Green");
Pampi
quelle
Dies wird nicht einmal kompiliert. Es gibt keine generische ParseMethode.
João Menighin
Es hat für mich zusammengestellt und funktioniert. Vielleicht hängt es von der Version ab, die Sie verwenden? Ich verwende .NET Core 3.1
Vinni
-1

Vielleicht möchten Sie auch einige der Vorschläge in diesem Blog-Beitrag lesen : Mein neuer kleiner Freund, Enum <T>

Der Beitrag beschreibt eine Möglichkeit, eine sehr einfache generische Hilfsklasse zu erstellen, mit der Sie die hässliche Casting-Syntax vermeiden können Enum.Parse- stattdessen schreiben Sie am Ende so etwas in Ihren Code:

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

Oder lesen Sie einige der Kommentare im selben Beitrag, in denen es um die Verwendung einer Erweiterungsmethode geht, um ähnliche Ergebnisse zu erzielen.

Julian Martin
quelle
Der Post-Link ist defekt.
Machado