Rechercher une chaîne dans Enum et renvoyer le Enum


163

J'ai une énumération:

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

et j'ai une chaîne:

string colour = "Red";

Je souhaite pouvoir revenir:

MyColours.Red

de:

public MyColours GetColour(string colour)

Jusqu'à présent, j'ai:

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

Comme vous pouvez le voir, je suis un peu coincé. Y a-t-il de toute façon pour sélectionner un énumérateur par valeur. Quelque chose comme:

MyColour(2) 

entraînerait

MyColour.Green


4
@nawfal, je n'ai pas trouvé ça quand j'ai demandé ça il y a toutes ces années. Ont voté pour fermer en double.
Matt Clarkson

Réponses:


381

consultez System.Enum.Parse:


enum Colors {Red, Green, Blue}

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


72
N'oubliez pas que vous pouvez le faire ignorer la casse en passant un troisième paramètre facultatif pour être "true"
Aerophilic

Exactement ce que je cherchais! À votre santé !
Zame

11
@ user1531040 En fait, il existe un Enum.TryParse.
DarLom

Notez que l'analyse enum «réussit» toujours si l'entrée est numérique; il renvoie simplement le nombre analysé, qui est ensuite converti en type enum. Donc, si vous voulez vérifier si une entrée utilisateur est une énumération valide ou autre chose, vous devez d'abord vérifier le contenu numérique. Comme il renvoie une énumération valide mais avec une valeur qui peut ne pas exister du tout dans les noms d'énumération définis, vous pouvez avoir des problèmes vraiment étranges.
Nyerguds

19

Vous pouvez convertir l'int en une énumération

(MyColour)2

Il existe également l'option Enum.Parse

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

11

Compte tenu des modifications les plus récentes et les plus importantes apportées à .NET (+ Core) et C # 7, voici la meilleure solution:

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

La variable de couleur peut être utilisée dans le cadre de Enum.TryParse



2

J'ai marqué la réponse d'OregonGhost +1, puis j'ai essayé d'utiliser l'itération et j'ai réalisé que ce n'était pas tout à fait correct car Enum.GetNames renvoie des chaînes. Vous voulez 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

Vous pouvez utiliser Enum.Parsepour obtenir une valeur d'énumération à partir du nom. Vous pouvez parcourir toutes les valeurs avecEnum.GetNames , et vous pouvez simplement convertir un int en une énumération pour obtenir la valeur enum de la valeur int.

Comme ceci, par exemple:

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
}

ou:

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

Ce dernier lancera une ArgumentException si la valeur n'est pas trouvée, vous voudrez peut-être l'attraper dans la fonction et renvoyer la valeur par défaut.


REMARQUE: Cela aurait dû être Enum.GetValues, bien sûr, comme indiqué dans la réponse de Colin.
OregonGhost

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

Cela ne compile même pas. Il n'y a pas de Parseméthode générique .
João Menighin

Il a été compilé et a fonctionné pour moi. Cela dépend peut-être de la version que vous utilisez? J'utilise .NET core 3.1
Vinni

0

Comme mentionné dans les réponses précédentes, vous pouvez convertir directement le type de données sous-jacent (int -> type enum) ou analyser (chaîne -> type enum).

mais attention - il n'y a pas de .TryParse pour les énumérations, vous aurez donc besoin d'un bloc try / catch autour de l'analyse pour détecter les échecs.


3
Ce n'était pas avant que cette question ne soit posée, mais maintenant il y en a depuis .NET 4! msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx . Ce serait quelque chose comme 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 # a une fonctionnalité intégrée pour cela.
Artemix

comment est-ce une réponse à la question? regardez les autres réponses pour un code beaucoup plus facile
Firo

0

Une chose qui pourrait vous être utile (en plus des réponses déjà valides / bonnes fournies jusqu'à présent) est l'idée StringEnum fournie ici

Avec cela, vous pouvez définir vos énumérations en tant que classes (les exemples sont dans vb.net):

<StringEnumRegisteredOnly (), DebuggerStepThrough (), ImmutableObject (True)> Classe publique NotInheritable eAuthenticationMethod hérite de 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")   

Fin de classe

Et maintenant, vous pouvez utiliser la classe this comme vous utiliseriez une énumération: eAuthenticationMethod.WindowsAuthentication et ce serait essentiellement comme attribuer au ' W ' la valeur logique de WindowsAuthentication (à l'intérieur de l'énumération) et si vous deviez afficher cette valeur à partir d'une propriété fenêtre (ou autre chose qui utilise la propriété System.ComponentModel.Description), vous obtiendrez " Utiliser l'authentification Windows ».

J'utilise cela depuis longtemps maintenant et cela rend le code plus clair dans l'intention.


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

-1

Vous pouvez également consulter certaines des suggestions de ce billet de blog: Mon nouveau petit ami, Enum <T>

Le message décrit un moyen de créer une classe d'assistance générique très simple qui vous permet d'éviter la vilaine syntaxe de conversion inhérente à Enum.Parse- au lieu de cela, vous finissez par écrire quelque chose comme ça dans votre code:

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

Ou consultez certains des commentaires dans le même article qui parlent de l'utilisation d'une méthode d'extension pour obtenir des résultats similaires.


Le lien de publication est rompu.
Machado
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.