2012-09-07 17 views
10

Aquí hay muchas preguntas sobre la conversión de cadenas a un valor enum. En general, la respuesta parece algo así como las respuestas de this question:¿Por qué devuelve Enum.Parse() un objeto?

StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true); 

Mientras que eso es una respuesta perfectamente razonable, y se puede escribir un método para simplificar la llamada, que no responde a la cuestión de qué Enum. Parse() devuelve un object en lugar del valor enum apropiado. ¿Por qué tengo que lanzarlo al StatusEnum?


Editar:

Básicamente, la pregunta es ¿por qué es una función como esta no es parte de la clase Enum?

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

Esta función funciona perfectamente bien, hace exactamente lo que cabría esperar. StatusEnum e = Enum.Parse<StatusEnum>("Active");.

+1

@ SpYk3HH - Los enumerados no * tienen * valores *. Ellos * son * valores. Son valores que tienen una sobrecarga habitual para '.ToString()', pero siguen siendo solo valores. – Bobson

+2

.NET 4.0+ tiene ['Enum.TryParse '] (http://msdn.microsoft.com/en-us/library/dd783499 (v = vs.100)) –

+0

@ SpYk3HH un valor de un tipo enum es algún entero que puede estar asociado con uno de los campos del tipo enum. El tamaño del número entero puede variar. Parse toma una cadena y devuelve una instancia encuadrada del tipo enum. Eso puede ser desempaquetado o no. Tu última oración tampoco tiene sentido. String y Boolean también tienen propiedades y métodos para trabajar. – phoog

Respuesta

10

Se hace esto porque

  1. era anterior a los genéricos y (aunque no había :)
  2. limitaciones genéricas no pueden ser enumeraciones (en los idiomas principales .NET)

Como tal, Object es el único tipo que siempre funcionará para cualquier tipo de enum.

Al devolver el objeto, la API funciona al menos, incluso si se requiere un lanzamiento.

+1

Si bien no puedes decir 'where t: Enum' puedes decir' where t: struct' y al menos eliminar los tipos de referencia, o no poner restricciones y evitar el molde/tipo de. – Guvante

+0

El hecho de que sea anterior a los genéricos no es una explicación. Sería un cambio sin interrupción agregar la función que edité arriba como una sobrecarga para el antiguo estilo 'Enum.Parse() '. – Bobson

+0

@Reed - Ahora que lo pienso, según tu lógica, Enum.TryParse () tampoco debería existir, pero lo hace. – Bobson

1

El tipo real del objeto es de hecho StatusEnum. El compilador y el código al escribir Enum.Parse no tienen idea de qué objeto de tiempo de ejecución será en el momento en que se escribe el método. No se conocerá hasta que se llame realmente el método.

3

TryParse apoya sin embargo un parámetro de tipo:

Enum.TryParse<FooEnum>(name, true, out ret);

Por lo tanto, si se especifica el valor ret como FooEnum ret;, usted no tendrá que convertirlo a FooEnum después; será del tipo adecuado de inmediato.

+0

Es cierto, pero ahora necesita dos líneas de código. Posiblemente tres. Uno para declarar 'ret', éste y otro para usarlo que de otro modo no hubieras necesitado. Esto plantea la pregunta de por qué hay una forma genérica de 'TryParse()' y no una forma genérica de 'Parse()'. – Bobson

+0

Probablemente se haya pasado por alto. Sin embargo, podría hacer su propia sobrecarga genérica como un método de extensión. – aevitas

+0

En realidad, no puedes. No puede extender 'Enum', porque es una clase estática. Entonces estarías llamando a 'EnumExtensions.Parse()' (o lo que sea que hayas llamado a tu clase), y no habría beneficio de ser un método de extensión. – Bobson

Cuestiones relacionadas