Busque una cadena en Enum y devuelva el Enum


163

Tengo una enumeración:

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

y tengo una cadena:

string colour = "Red";

Quiero poder volver:

MyColours.Red

de:

public MyColours GetColour(string colour)

Hasta ahora tengo:

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 puede ver, estoy un poco atascado. ¿Hay alguna forma de seleccionar un enumerador por valor? Algo como:

MyColour(2) 

daría como resultado

MyColour.Green


44
@nawfal, no encontré eso cuando pregunté esto hace tantos años. He votado para cerrar como duplicado.
Matt Clarkson

Respuestas:


381

echa un vistazo a System.Enum.Parse:


enum Colors {Red, Green, Blue}

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


72
No olvide que puede hacer que ignore mayúsculas y minúsculas pasando un tercer parámetro opcional para que sea "verdadero"
Aerofílico

Exactamente lo que estaba buscando ! Salud !
Zame

11
@ user1531040 En realidad, hay un Enum. TryParse.
DarLom

Tenga en cuenta que el análisis de enumeración siempre 'tiene éxito' si la entrada es numérica; solo devuelve el número analizado, que luego se convierte al tipo de la enumeración. Entonces, si desea verificar si alguna entrada del usuario es una enumeración válida o algo más, primero debe verificar el contenido numérico. Como devuelve una enumeración válida pero con un valor que puede no existir en absoluto en los nombres de enumeración definidos, puede obtener algunos problemas realmente extraños.
Nyerguds

19

Puedes convertir el int en una enumeración

(MyColour)2

También existe la opción de Enum.

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

11

Dados los últimos y mejores cambios en .NET (+ Core) y C # 7, esta es la mejor solución:

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

La variable de color se puede utilizar dentro del alcance de Enum. TryParse



2

Marqué la respuesta de OregonGhost +1, luego intenté usar la iteración y me di cuenta de que no estaba del todo bien porque Enum.GetNames devuelve cadenas. Desea 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

Puede usar Enum.Parsepara obtener un valor de enumeración del nombre. Puede iterar sobre todos los valores con Enum.GetNames, y simplemente puede convertir un int en una enumeración para obtener el valor de enumeración del valor int.

Así, por ejemplo:

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
}

Este último arrojará una ArgumentException si no se encuentra el valor, es posible que desee atraparlo dentro de la función y devolver el valor predeterminado.


NOTA: Debería haber sido Enum.GetValues, por supuesto, como se muestra en la respuesta de Colin.
OregonGhost

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

Esto ni siquiera compila. No hay un Parsemétodo genérico .
João Menighin

Se compiló y funcionó para mí. ¿Tal vez depende de la versión que estés usando? Estoy usando .NET core 3.1
Vinni

0

Como se mencionó en las respuestas anteriores, puede transmitir directamente al tipo de datos subyacente (int -> tipo de enumeración) o analizar (cadena -> tipo de enumeración).

pero tenga cuidado: no hay. TryParse para las enumeraciones, por lo que necesitará un bloque try / catch alrededor del análisis para detectar fallas.


3
No fue antes de que se hiciera esta pregunta, ¡pero ahora existe desde .NET 4! msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx . Sería algo así como Enum. TryParse <MyColour> ("Rojo", fuera de 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 # tiene una funcionalidad incorporada para esto.
Artemix

¿Cómo es esto una respuesta a la pregunta? mira las otras respuestas para un código mucho más fácil
Firo

0

Una cosa que podría serle útil (además de las respuestas válidas / buenas proporcionadas hasta ahora) es la idea de StringEnum proporcionada aquí

Con esto puede definir sus enumeraciones como clases (los ejemplos están en vb.net):

<StringEnumRegisteredOnly (), DebuggerStepThrough (), ImmutableObject (True)> Public NotInheritable Class eAuthenticationMethod hereda 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")   

Clase final

Y ahora podría usar esta clase como usaría una enumeración: eAuthenticationMethod.WindowsAuthentication y esto sería esencialmente como asignar ' W ' al valor lógico de WindowsAuthentication (dentro de la enumeración) y si fuera a ver este valor desde una propiedad ventana (u otra cosa que use la propiedad System.ComponentModel.Description) obtendría " Usar autenticación de Windows ".

He estado usando esto durante mucho tiempo y hace que el código sea más claro en su intención.


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

-1

También puede consultar algunas de las sugerencias en esta publicación de blog: Mi nuevo amigo, Enum <T>

La publicación describe una forma de crear una clase auxiliar genérica muy simple que le permite evitar la sintaxis de conversión fea inherente a Enum.Parse- en su lugar, termina escribiendo algo como esto en su código:

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

O echa un vistazo a algunos de los comentarios en la misma publicación que hablan sobre el uso de un método de extensión para lograr algo similar.


El enlace de la publicación está roto.
Machado
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.