Pregunta

Me gustaría crear un método genérico para la conversión de cualquier tipo derivado System.Enum a su valor entero correspondiente, sin colada y preferiblemente sin necesidad de analizar una cadena.

Por ejemplo, lo que quiero es algo como esto:

// Trivial example, not actually what I'm doing.
class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        (int)anEnum;
    }
}

Sin embargo, esto no parece funcionar. ReSharper informa de que no se puede convertir la expresión del tipo 'System.Enum' al tipo 'int'.

Ahora que hemos llegado con esta solución pero prefiero tener algo más eficiente.

class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        return int.Parse(anEnum.ToString("d"));
    }
}

¿Alguna sugerencia?

¿Fue útil?

Solución

Si no desea emitir,

Convert.ToInt32()

podría hacer el truco.

El elenco directa (a través de (int)enumValue) no es posible. Tenga en cuenta que esto también sería "peligroso", ya que una enumeración puede tener diferentes tipos subyacentes (int, long, byte ...).

Más formalmente: System.Enum tiene ninguna relación directa con la herencia Int32 (aunque ambos son ValueTypes), por lo que la conversión explícita no puede ser correcta dentro del sistema de tipos

Otros consejos

Lo tengo que trabajar por colada a un objeto y luego a un int:

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return (int)((object)enumValue);
    }
}

Esto es feo y probablemente no sea la mejor manera. Voy a seguir jugando con él, a ver si puedo llegar a algo mejor ....

EDIT:. Estaba a punto de publicar que Convert.ToInt32 (enumValue) funciona tan bien, y se dio cuenta de que MartinStettner me adelantó

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

Prueba:

int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday

EDIT 2: En los comentarios, alguien dijo que esto sólo funciona en C # 3.0. Acabo de probar esto en VS2005 como esto y funcionó:

public static class Helpers
{
    public static int ToInt(Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

    static void Main(string[] args)
    {
        Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
    }

Si usted necesita para convertir cualquier enum a su tipo subyacente (no todas las enumeraciones están respaldados por int), puede utilizar:

return System.Convert.ChangeType(
    enumValue,
    Enum.GetUnderlyingType(enumValue.GetType()));

¿Por qué es necesario reinventar la rueda con un método de ayuda? Es perfectamente legal para emitir un valor enum a su tipo subyacente.

Es menos escribir, y en mi opinión más fácil de leer, usar ...

int x = (int)DayOfWeek.Tuesday;

... en lugar de algo así como ...

int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();

Desde mi respuesta aquí :

Dado e como en:

Enum e = Question.Role;

A continuación, estos trabajos:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

Los dos últimos son feo llano. El primero de ellos debería ser más fácil de leer, aunque el segundo es mucho más rápido. O puede ser un método de extensión es la mejor, lo mejor de ambos mundos.

public static int GetIntValue(this Enum e)
{
    return e.GetValue<int>();
}

public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
    return (T)(object)e;
}

Ahora se puede llamar a:

e.GetValue<int>(); //or
e.GetIntValue();

Colada de System.Enum a un int funciona bien para mí (que es también en la MSDN ). Tal vez sea un error ReSharper.

Desde enumeraciones se limitan a byte, sbyte, corta, ushort, int, uint largo y ulong, podemos hacer algunas suposiciones.

Podemos evitar excepciones durante la conversión mediante el uso de la más grande de contenedores disponibles. Por desgracia, recipiente a utilizar no está claro porque ulong va a explotar para los números negativos y largo va a explotar para los números entre long.MaxValue y ulong.MaxValue. Tenemos que cambiar entre estas opciones en función del tipo subyacente.

Por supuesto, usted todavía tiene que decidir qué hacer cuando el resultado no encaja dentro de un int. Creo que la colada está bien, pero todavía hay algunos aspectos críticos:

  1. para enumeraciones basado en un tipo con un espacio de terreno más grande que int (largo y ulong), es posible que algunas enumeraciones evaluarán en el mismo valor.
  2. echando un número mayor que int.MaxValue lanzará una excepción si se encuentra en una región marcada.

Esto es mi sugerencia, lo dejaré al lector para decidir dónde exponer esta función; como un ayudante o una extensión.

public int ToInt(Enum e)
{
  unchecked
  {
    if (e.GetTypeCode() == TypeCode.UInt64)
      return (int)Convert.ToUInt64(e);
    else
      return (int)Convert.ToInt64(e);
  }
}

No se olvide que el propio tipo de enumeración tiene un montón de funciones de ayuda estáticas en el mismo. Si todo lo que quieres hacer es convertir una instancia de la enumeración correspondiente a su tipo entero, a continuación, la fundición es probablemente la manera más eficiente.

Creo ReSharper se queja porque enumeración no es una enumeración de cualquier tipo particular, y los propios enumeraciones derivan de una valuetype escalar, no Enum. Si necesita fundición adaptables de forma genérica, yo diría que esto podría Suite que también (tenga en cuenta que el propio tipo de enumeración también se incluye en el genérica:

public static EnumHelpers
{
    public static T Convert<T, E>(E enumValue)
    {
        return (T)enumValue;
    }
}

Esto podría ser utilizado de esta manera:

public enum StopLight: int
{
    Red = 1,
    Yellow = 2,
    Green = 3
}

// ...

int myStoplightColor = EnumHelpers.Convert<int, StopLight>(StopLight.Red);

No puedo decir con seguridad fuera de la parte superior de la cabeza, pero el código anterior podría incluso ser apoyado por la inferencia de tipos de C # 's, lo que permite lo siguiente:

int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top