Cómo obtener el valor de enumeración por cadena o int

108

¿Cómo puedo obtener el valor de enumeración si tengo la cadena de enumeración o el valor int de enumeración? por ejemplo: si tengo una enumeración de la siguiente manera:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

y en alguna variable de cadena tengo el valor "valor1" de la siguiente manera:

string str = "Value1" 

o en alguna variable int tengo el valor 2 como

int a = 2;

¿Cómo puedo obtener la instancia de enum? Quiero un método genérico donde pueda proporcionar la enumeración y mi cadena de entrada o valor int para obtener la instancia de enumeración.

Abhishek Gahlout
fuente
posible duplicado de Get enum int value por cadena

Respuestas:

210

No, no quieres un método genérico. Esto es mucho más fácil:

MyEnum myEnum = (MyEnum)myInt;

MyEnum myEnum = (MyEnum)Enum.Parse(typeof(MyEnum), myString);

Creo que también será más rápido.

Kendall Frey
fuente
En realidad, esta es la forma correcta de hacerlo. No existe una forma genérica de analizar tipos por la misma razón por la que no existe una interfaz IParsable.
Johannes
1
@Johannes ¿Qué quieres decir con eso? Hay una forma genérica, refiera mi respuesta y otras también.
Sriram Sakthivel
1
@SriramSakthivel El problema que describe el OP se resuelve como lo mostró KendallFrey. No se puede realizar el análisis genérico; consulte aquí: informit.com/blogs/blog.aspx?uk=Why-no-IParseable-interface . Cualquier otra solución no tiene ninguna ventaja en comparación con la solución "integrada" de C #. El máximo que puede tener es un ICanSetFromString <T> donde crea e inicializa un objeto a su valor predeterminado (T) y en el siguiente paso pasa una cadena representativa. Esto se acerca a la respuesta que dio el OP, pero no tiene sentido porque generalmente se trata de un problema de diseño y se pasó por alto un punto más importante en el diseño del sistema.
Johannes
Esta respuesta funcionó muy bien, especialmente con los múltiples ejemplos de un uso de int y string. Gracias.
Termato
1
Creo que esto funciona ahora, es un poco más conciso: Enum.Parse <MyEnum> (myString);
Phil B
32

Hay numerosas formas de hacer esto, pero si desea un ejemplo simple, esto será suficiente. Solo debe mejorarse con la codificación defensiva necesaria para verificar la seguridad del tipo y el análisis no válido, etc.

    /// <summary>
    /// Extension method to return an enum value of type T for the given string.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this string value)
    {
        return (T) Enum.Parse(typeof(T), value, true);
    }

    /// <summary>
    /// Extension method to return an enum value of type T for the given int.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this int value)
    {
        var name = Enum.GetName(typeof(T), value);
        return name.ToEnum<T>();
    }
David Spenard
fuente
17

Podría ser mucho más simple si usa los métodos TryParseo Parsey ToObject.

public static class EnumHelper
{
    public static  T GetEnumValue<T>(string str) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }
        T val;
        return Enum.TryParse<T>(str, true, out val) ? val : default(T);
    }

    public static T GetEnumValue<T>(int intValue) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }

        return (T)Enum.ToObject(enumType, intValue);
    }
}

Como señaló @chrfin en los comentarios, puede convertirlo en un método de extensión muy fácilmente simplemente agregando thisantes del tipo de parámetro que puede ser útil.

Sriram Sakthivel
fuente
2
Ahora también agregue un thisal parámetro y haga EnumHelperestático y también puede usarlos como extensiones (vea mi respuesta, pero tiene un código mejor / completo para el resto) ...
Christoph Fink
@chrfin Buena idea, pero no la prefiero, ya que aparecerá en intellisense donde no es necesario cuando tenemos espacios de nombres en el alcance. Supongo que será molesto.
Sriram Sakthivel
1
@chrfin Gracias por el comentario, agregado como nota en mi respuesta.
Sriram Sakthivel
5

A continuación se muestra el método en C # para obtener el valor de enumeración por cadena

///
/// Method to get enumeration value from string value.
///
///
///

public T GetEnumValue<T>(string str) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];
    if (!string.IsNullOrEmpty(str))
    {
        foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
        {
            if (enumValue.ToString().ToUpper().Equals(str.ToUpper()))
            {
                val = enumValue;
                break;
            }
        }
    }

    return val;
}

A continuación se muestra el método en C # para obtener el valor de enumeración por int.

///
/// Method to get enumeration value from int value.
///
///
///

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];

    foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
    {
        if (Convert.ToInt32(enumValue).Equals(intValue))
        {
            val = enumValue;
            break;
        }             
    }
    return val;
}

Si tengo una enumeración de la siguiente manera:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

entonces puedo hacer uso de los métodos anteriores como

TestEnum reqValue = GetEnumValue<TestEnum>("Value1");  // Output: Value1
TestEnum reqValue2 = GetEnumValue<TestEnum>(2);        // OutPut: Value2

Espero que esto ayude.

Abhishek Gahlout
fuente
4
¿Puede también proporcionar una referencia de dónde consiguió esto?
JonH
Para que esto se compile, tuve que modificar la primera línea a public T GetEnumValue <T> (int intValue) donde T: struct, IConvertible También tenga cuidado con un '}' adicional al final
Avi
3

Creo que olvidaste la definición de tipo genérico:

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible // <T> added

y puede mejorarlo para que sea más conveniente como, por ejemplo:

public static T ToEnum<T>(this string enumValue) : where T : struct, IConvertible
{
    return (T)Enum.Parse(typeof(T), enumValue);
}

entonces puedes hacer:

TestEnum reqValue = "Value1".ToEnum<TestEnum>();
Christoph Fink
fuente
2

Prueba algo como esto

  public static TestEnum GetMyEnum(this string title)
        {    
            EnumBookType st;
            Enum.TryParse(title, out st);
            return st;          
         }

Para que puedas hacer

TestEnum en = "Value1".GetMyEnum();
Humpty Dumpty
fuente
2

De la base de datos SQL, obtenga una enumeración como:

SqlDataReader dr = selectCmd.ExecuteReader();
while (dr.Read()) {
   EnumType et = (EnumType)Enum.Parse(typeof(EnumType), dr.GetString(0));
   ....         
}
RFE Petr
fuente
2

Simplemente prueba esto

Es de otra manera

public enum CaseOriginCode
{
    Web = 0,
    Email = 1,
    Telefoon = 2
}

public void setCaseOriginCode(string CaseOriginCode)
{
    int caseOriginCode = (int)(CaseOriginCode)Enum.Parse(typeof(CaseOriginCode), CaseOriginCode);
}
Eliahu Aaron
fuente
0

Aquí hay un ejemplo para obtener una cadena / valor

    public enum Suit
    {
        Spades = 0x10,
        Hearts = 0x11,
        Clubs = 0x12,
        Diamonds = 0x13
    }

    private void print_suit()
    {
        foreach (var _suit in Enum.GetValues(typeof(Suit)))
        {
            int suitValue = (byte)(Suit)Enum.Parse(typeof(Suit), _suit.ToString());
            MessageBox.Show(_suit.ToString() + " value is 0x" + suitValue.ToString("X2"));
        }
    }

    Result of Message Boxes
    Spade value is 0x10
    Hearts value is 0x11
    Clubs value is 0x12
    Diamonds value is 0x13
Daniel Jeong
fuente
0

Puede usar el siguiente método para hacer eso:

public static Output GetEnumItem<Output, Input>(Input input)
    {
        //Output type checking...
        if (typeof(Output).BaseType != typeof(Enum))
            throw new Exception("Exception message...");

        //Input type checking: string type
        if (typeof(Input) == typeof(string))
            return (Output)Enum.Parse(typeof(Output), (dynamic)input);

        //Input type checking: Integer type
        if (typeof(Input) == typeof(Int16) ||
            typeof(Input) == typeof(Int32) ||
            typeof(Input) == typeof(Int64))

            return (Output)(dynamic)input;

        throw new Exception("Exception message...");
    }

Nota: este método es solo una muestra y puedes mejorarlo.

Mohamad Bahmani
fuente