Cerca una stringa in Enum e restituisci Enum


163

Ho un elenco:

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

e ho una stringa:

string colour = "Red";

Voglio essere in grado di tornare:

MyColours.Red

a partire dal:

public MyColours GetColour(string colour)

Finora ho:

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

Come puoi vedere, sono un po 'bloccato. Esiste comunque una selezione di un enumeratore per valore. Qualcosa di simile a:

MyColour(2) 

si tradurrebbe in

MyColour.Green


4
@nawfal, non l'ho trovato quando l'ho chiesto tutti quegli anni fa. Hanno votato per chiudere come duplicato.
Matt Clarkson,

Risposte:


381

controlla System.Enum.Parse:


enum Colors {Red, Green, Blue}

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


72
Non dimenticare che puoi ignorare la distinzione tra maiuscole e minuscole passando un terzo parametro opzionale per essere "vero"
Aerophilic

Esattamente quello che stavo cercando! Saluti !
Zame,

11
@ user1531040 In realtà, esiste un Enum.TryParse.
DarLom,

Si noti che l'analisi dell'enum 'riesce sempre' se l'input è numerico; restituisce semplicemente il numero analizzato, che viene quindi castato nel tipo di enum. Quindi, se si desidera verificare se l'input di un utente è un enum valido o qualcos'altro, è necessario verificare prima il contenuto numerico. Dal momento che restituisce un enum valido ma con un valore che potrebbe non esistere affatto nei nomi enum definiti, è possibile che si verifichino problemi davvero strani.
Nyerguds

19

Puoi lanciare l'int in un enum

(MyColour)2

C'è anche l'opzione di Enum.Parse

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

11

Date le ultime e più grandi modifiche a .NET (+ Core) e C # 7, ecco la soluzione migliore:

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

la variabile colore può essere utilizzata nell'ambito di Enum.TryParse



2

Ho contrassegnato la risposta +1 di OregonGhost, quindi ho provato a utilizzare l'iterazione e mi sono reso conto che non era del tutto corretto perché Enum.GetNames restituisce stringhe. Volete 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

È possibile utilizzare Enum.Parseper ottenere un valore enum dal nome. Puoi iterare su tutti i valori con Enum.GetNamese puoi semplicemente lanciare un int in un enum per ottenere il valore enum dal valore int.

In questo modo, ad esempio:

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
}

o:

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

Quest'ultimo genererà una ArgumentException se il valore non viene trovato, è possibile catturarlo all'interno della funzione e restituire il valore predefinito.


NOTA: avrebbe dovuto essere Enum.GetValues, ovviamente, come mostrato nella risposta di Colin.
OregonGhost

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

Questo non si compila nemmeno. Non esiste un Parsemetodo generico .
João Menighin,

Ha compilato e ha funzionato per me. Forse dipende dalla versione che stai usando? Sto usando .NET core 3.1
Vinni

0

Come menzionato nelle risposte precedenti, è possibile eseguire il cast direttamente sul tipo di dati sottostante (int -> tipo enum) o sull'analisi (stringa -> tipo enum).

ma attenzione: non esiste. TryParse per gli enum, quindi avrai bisogno di un blocco try / catch attorno all'analisi per rilevare gli errori.


3
Non era prima che questa domanda fosse posta, ma ora c'è .NET 4! msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx . Sarebbe qualcosa di simile a Enum. TryParse <MyColour> ("Red", out color)
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 # ha funzionalità integrate per questo.
Artemix,

come è una risposta alla domanda? guarda le altre risposte per un codice molto più semplice
Firo,

0

Una cosa che potrebbe esserti utile (oltre alle risposte già valide / buone fornite finora) è l'idea StringEnum fornita qui

Con questo puoi definire le tue enumerazioni come classi (gli esempi sono in vb.net):

<StringEnumRegisteredOnly (), DebuggerStepThrough (), ImmutableObject (True)> Classe NotInheritable pubblica eAuthenticationMethod Eredita 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")   

End Class

E ora potresti usare questa classe come faresti con un enum: eAuthenticationMethod.WindowsAuthentication e questo sarebbe essenzialmente come assegnare a ' W ' il valore logico di WindowsAuthentication (all'interno dell'enum) e se dovessi visualizzare questo valore da una proprietà finestra (o qualcos'altro che utilizza la proprietà System.ComponentModel.Description) otterrai " Usa autenticazione di Windows ".

Lo sto usando da molto tempo ormai e rende il codice più chiaro nelle intenzioni.


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

-1

Potresti anche dare un'occhiata ad alcuni dei suggerimenti in questo post del blog: Il mio nuovo piccolo amico, Enum <T>

Il post descrive un modo per creare una classe helper generica molto semplice che ti consente di evitare la brutta sintassi del casting inerente a Enum.Parse- invece finisci per scrivere qualcosa di simile nel tuo codice:

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

Oppure dai un'occhiata ad alcuni dei commenti nello stesso post che parlano dell'utilizzo di un metodo di estensione per ottenere risultati simili.


Il link al post è interrotto.
Machado,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.