Pregunta

Tengo un valor Int16, a partir de la base de datos, y la necesidad de convertir esto en un tipo de enumeración. Desgraciadamente, esto es hecho en una capa del código que sabe muy poco acerca de los objetos a excepción de lo que pueda reunir a través de la reflexión.

Como tal, termina llamando Convert.ChangeType el que falla con una excepción reparto no válido.

He encontrado lo que considero una solución maloliente, como esto:

String name = Enum.GetName(destinationType, value);
Object enumValue = Enum.Parse(destinationType, name, false);

¿Hay una mejor manera, para que yo no tenga que moverse a través de esta operación de cuerdas?

He aquí una breve, pero completa, programa que puede ser utilizado si alguien tiene que experimentar:

using System;

public class MyClass
{
    public enum DummyEnum
    {
        Value0,
        Value1
    }

    public static void Main()
    {
        Int16 value = 1;
        Type destinationType = typeof(DummyEnum);

        String name = Enum.GetName(destinationType, value);
        Object enumValue = Enum.Parse(destinationType, name, false);

        Console.WriteLine("" + value + " = " + enumValue);
    }
}
¿Fue útil?

Solución

Enum.ToObject(.... es lo que está buscando!

C #

StringComparison enumValue = (StringComparison)Enum.ToObject(typeof(StringComparison), 5);

VB.NET

Dim enumValue As StringComparison = CType([Enum].ToObject(GetType(StringComparison), 5), StringComparison)

Si usted hace un montón de Enum conversión de tratar de usar la siguiente clase que le ahorrará una gran cantidad de código.

public class Enum<EnumType> where EnumType : struct, IConvertible
{

    /// <summary>
    /// Retrieves an array of the values of the constants in a specified enumeration.
    /// </summary>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType[] GetValues()
    {
        return (EnumType[])Enum.GetValues(typeof(EnumType));
    }

    /// <summary>
    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType Parse(string name)
    {
        return (EnumType)Enum.Parse(typeof(EnumType), name);
    }

    /// <summary>
    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="ignoreCase"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType Parse(string name, bool ignoreCase)
    {
        return (EnumType)Enum.Parse(typeof(EnumType), name, ignoreCase);
    }

    /// <summary>
    /// Converts the specified object with an integer value to an enumeration member.
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType ToObject(object value)
    {
        return (EnumType)Enum.ToObject(typeof(EnumType), value);
    }
}

Ahora, en lugar de escribir (StringComparison)Enum.ToObject(typeof(StringComparison), 5); simplemente puede escribir Enum<StringComparison>.ToObject(5);.

Otros consejos

Sobre la base de la respuesta de Pedro @ aquí es el método para Nullable<int> a Enum conversión:

public static class EnumUtils
{
        public static bool TryParse<TEnum>(int? value, out TEnum result)
            where TEnum: struct, IConvertible
        {
            if(!value.HasValue || !Enum.IsDefined(typeof(TEnum), value)){
                result = default(TEnum);
                return false;
            }
            result = (TEnum)Enum.ToObject(typeof(TEnum), value);
            return true;
        }
}

El uso de EnumUtils.TryParse<YourEnumType>(someNumber, out result) llega a ser útil para muchos escenarios. Por ejemplo, WebAPI controlador en Asp.NET no tiene protección contra defecto params Enum no válidos. Asp.NET simplemente utilizará default(YourEnumType) valor, incluso si algunos pases null, -1000, 500000, "garbage string" o ignora totalmente el parámetro. Por otra parte, ModelState será válida en todos estos casos, por lo que una de las soluciones es utilizar int? tipo de comprobación personalizada

public class MyApiController: Controller
{
    [HttpGet]
    public IActionResult Get(int? myEnumParam){    
        MyEnumType myEnumParamParsed;
        if(!EnumUtils.TryParse<MyEnumType>(myEnumParam, out myEnumParamParsed)){
            return BadRequest($"Error: parameter '{nameof(myEnumParam)}' is not specified or incorrect");
        }      

        return this.Get(washingServiceTypeParsed);            
    }
    private IActionResult Get(MyEnumType myEnumParam){ 
       // here we can guarantee that myEnumParam is valid
    }

Si va a guardar una enumeración en un DataTable, pero no sabe qué columna es una enumeración y que es una cadena / int, se puede acceder al valor de esta manera:

foreach (DataRow dataRow in myDataTable.Rows)
{
    Trace.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
    foreach (DataColumn dataCol in myDataTable.Columns)
    {
        object v = dataRow[dataCol];
        Type t = dataCol.DataType;
        bool e = false;
        if (t.IsEnum) e = true;

        Trace.WriteLine((dataCol.ColumnName + ":").PadRight(30) +
            (e ? Enum.ToObject(t, v) : v));
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top