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
Matt Clarkson
fuente
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");

JMarsch
fuente
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")
Guvante
fuente
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

romano
fuente
5

Todo lo que necesitas es Enum .

Bruno Brant
fuente
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;
}
Colin
fuente
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.

OregonGhost
fuente
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");
pampi
fuente
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.

Addys
fuente
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);
        }
    }
}
Raja
fuente
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.

Ando
fuente
0
(MyColours)Enum.Parse(typeof(MyColours), "red", true); // MyColours.Red
(int)((MyColours)Enum.Parse(typeof(MyColours), "red", true)); // 0
Sandeep Shekhawat
fuente
-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.

Julian Martin
fuente
El enlace de la publicación está roto.
Machado