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.


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.


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>();
    }

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.


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.


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>();

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();

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

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);
}

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

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.

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.