Procure uma string no Enum e retorne o Enum

163

Eu tenho uma enumeração:

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

e eu tenho uma string:

string colour = "Red";

Quero poder retornar:

MyColours.Red

de:

public MyColours GetColour(string colour)

Até agora eu tenho:

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

Como você pode ver, estou um pouco preso. Existe uma maneira de selecionar um enumerador por valor. Algo como:

MyColour(2) 

resultaria em

MyColour.Green
Matt Clarkson
fonte
4
@nawfal, não achei isso quando perguntei isso todos esses anos atrás. Votaram para fechar como duplicado.
Matt Clarkson

Respostas:

381

confira System.Enum.Parse:


enum Colors {Red, Green, Blue}

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

JMarsch
fonte
72
Não esqueça que você pode tê-lo ignorar maiúsculas e minúsculas passando um terceiro parâmetro opcional para ser "verdadeira"
Aerophilic
Exatamente o que eu estava procurando ! Felicidades !
Zame 20/10/19
11
@ user1531040 Na verdade, existe um Enum.TryParse.
DarLom 1/11
Observe que a análise de enum sempre 'é bem-sucedida' se a entrada for numérica; apenas retorna o número analisado, que é convertido no tipo de enumeração. Portanto, se você quiser verificar se alguma entrada do usuário é uma enumeração válida ou algo mais, verifique primeiro o conteúdo numérico. Como ele retorna uma enum válida, mas com um valor que pode não existir nos nomes de enum definidos, você pode obter alguns problemas realmente estranhos.
Nyerguds 03/03
19

Você pode converter o int para um enum

(MyColour)2

Há também a opção de Enum.Parse

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

Dadas as maiores e mais recentes mudanças no .NET (+ Core) e C # 7, eis a melhor solução:

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

variável de cor pode ser usada no escopo de Enum.TryParse

romano
fonte
5

Tudo que você precisa é Enum.Parse .

Bruno Brant
fonte
2

Marquei a resposta do OregonGhost como +1, depois tentei usar a iteração e percebi que não estava certo porque o Enum.GetNames retorna strings. Você deseja 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
fonte
1

Você pode usar Enum.Parsepara obter um valor de enumeração do nome. Você pode iterar sobre todos os valores comEnum.GetNames e pode apenas converter um int em uma enumeração para obter o valor de enumeração do valor int.

Assim, por exemplo:

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
}

O último lançará uma ArgumentException se o valor não for encontrado. Você pode capturá-lo dentro da função e retornar o valor padrão.

OregonGhost
fonte
OBSERVAÇÃO: Deveria ter sido Enum.GetValues, como mostra a resposta de Colin.
OregonGhost
1
var color =  Enum.Parse<Colors>("Green");
pampi
fonte
Isso nem compila. Não há Parsemétodo genérico .
João Menighin 12/03/19
Compilou e trabalhou para mim. Talvez isso depende da versão que você está usando? Estou usando o .NET core 3.1
Vinni
0

Conforme mencionado nas respostas anteriores, você pode converter diretamente para o tipo de dados subjacente (tipo int -> enum) ou analisar (string -> tipo enum).

mas tenha cuidado - não há .TryParse para enumerações, portanto, você precisará de um bloco try / catch em torno da análise para detectar falhas.

Addys
fonte
3
Não foi antes desta pergunta ser feita, mas agora existe a partir do .NET 4! msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx . Seria algo como Enum.TryParse <MyColour> ( "Red", a cor)
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);
        }
    }
}
Rajá
fonte
2
C # possui funcionalidade interna para isso.
Artemix 28/11/2012
como isso é uma resposta para a pergunta? olhar para as outras respostas para o código muito mais fácil
Firo
0

Uma coisa que pode ser útil para você (além das respostas já válidas / boas fornecidas até agora) é a idéia StringEnum fornecida aqui

Com isso, você pode definir suas enumerações como classes (os exemplos estão em vb.net):

<StringEnumRegisteredOnly (), DebuggerStepThrough (), ImmutableObject (True)> Classe pública NotInheritable 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")   

Classe final

E agora você pode usar a classe this como usaria uma enum: eAuthenticationMethod.WindowsAuthentication e isso seria essencialmente como atribuir a ' W ' o valor lógico do WindowsAuthentication (dentro da enum) e se você exibir esse valor em uma propriedade janela (ou qualquer outra coisa que use a propriedade System.ComponentModel.Description), você obteria " Usar autenticação do Windows ".

Estou usando isso há muito tempo e isso torna o código mais claro na intenção.

Ando
fonte
0
(MyColours)Enum.Parse(typeof(MyColours), "red", true); // MyColours.Red
(int)((MyColours)Enum.Parse(typeof(MyColours), "red", true)); // 0
Sandeep Shekhawat
fonte
-1

Você também pode conferir algumas sugestões nesta postagem do blog: Meu novo amiguinho, Enum <T>

A publicação descreve uma maneira de criar uma classe auxiliar genérica muito simples, que permite evitar a sintaxe de conversão feia inerente a Enum.Parse- em vez disso, você acaba escrevendo algo assim no seu código:

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

Ou confira alguns dos comentários no mesmo post que falam sobre o uso de um método de extensão para obter resultados semelhantes.

Julian Martin
fonte
O link da postagem está quebrado.
Machado