2009-10-29 45 views
18

(OK, voy a exponer el fondo de mi ignorancia aquí, por favor ser suave)No se puede convertir tipo 'System.Enum' a int

Antecedentes

Tengo un método que se ve (un poco) de esta manera:

public void AddLink(Enum enumVal) 
{ 
    string identifier = m_EnumInterpreter(enumVal); 
    AddLink(identifier); 
} 

el EnumInterpreter es un Func < Enum, string> que se pasa cuando se crea la clase padre.

Estoy usando Enum porque en este nivel no es de mi incumbencia, no me importa qué enumeración específica es. El código de llamada solo usa una enumeración (generada) para evitar cadenas mágicas.

Pregunta

Si el EnumInterpreter devuelve una cadena vacía, me gustaría lanzar una excepción con el valor real de enumVal. Pensé que solo podría convertir a int, pero el compilador no lo tendrá. ¿Qué estoy haciendo mal? (Por favor, no digas 'todo').

+1

posible duplicado de [¿Cómo convertir de System.Enum a base entera?] (Http://stackoverflow.com/questions/908543/how-to-convert-from-system-enum-to-base-integer) – nawfal

Respuesta

5

No, no puede convertirlo a int porque System.Enum no es una enumeración, es solo la clase base para enumeraciones.

EDIT:

se puede obtener el valor de la siguiente manera, pero es feo:

int intVar = (int)enuYourEnum.GetType().GetField("value__").GetValue(objYourEnum); 
+7

Sí, eso es feo. – Benjol

+1

Tenga en cuenta que esto fallará si 'int' es * no * el tipo subyacente de la enumeración. –

+0

Bueno, debo confesar que no lo es, es un error, pero creo que he encontrado algo que funciona para mí ... – Benjol

33

System.Enum no se puede convertir directamente en entero, pero sí poner en práctica de manera explícita IConvertible, lo que significa que puede utilice la siguiente:

public void AddLink(Enum enumVal) 
{ 
    string identifier = m_EnumInterpreter(Convert.ToInt32(enumVal)); 
    AddLink(identifier); 
} 

Tenga en cuenta que si su enumeración en realidad está utilizando algo que no sea un número entero (como un flotador), si no se pierden los datos no enteros sobre conv ersion. O sea evidente reemplazar la llamada Convert con lo que va a convertir a partir de (si se conoce)

+7

C# enumeraciones no pueden ser flotantes: http://msdn.microsoft.com/en- us/library/sbbt4032% 28VS.71% 29.aspx - ** Cada tipo de enumeración tiene un tipo subyacente, que puede ser de tipo integral ** –

1

Varias cosas aquí:

1) la respuesta de Ryan se ve bien, pero ... yo preferiría pasar el Enum hasta el intérprete enum, para que puedas hacer todo el Convert.To ... allí. Si sabe que está utilizando SÓLO enums basados ​​en enteros, Convert.ToInt32() está bien. De lo contrario, es posible que desee agregar usando el reflejo o intente/capture otras conversiones.

2) También puede considerar el uso de miembros de la clase Enum, como .GetName(), .GetValue(), etc. ya que tratan directamente con los nombres definidos y valores independientes del tipo enum.

3) técnicamente no lanzaría la excepción fuera del intérprete enum. Si esa condición es generalmente verdadera, ejecute la excepción desde el intérprete enum, para que todos los usos de la clase se beneficien de la validación. O podrías terminar duplicando el código.

4) parece que tiene un fondo C++/MFC a juzgar por su nomenclatura variable. Es posible que desee entrar en convenciones de nomenclatura de estilo C#, le facilitará la vida al usar/leer el código y las bibliotecas de otras personas. Eche un vistazo a StyleCop de MS para obtener un buen complemento que lo ayude a nombrar.

+0

1) en realidad no es así, pero nada lo dicta. 2) La implementación actual (única) de EnumInterpreter realmente usa Enum.GetName(), GetValue() no existe. 3) Dado que EnumInterpreter PUEDE pasarse/anularse desde el exterior, no quería confiar demasiado. 4) Trabajo con personas con ese trasfondo, y estuvieron aquí antes que yo para decidir la convención de nombres, pero verificaría su sugerencia. – Benjol

+0

Sí, lo siento, es en realidad .GetValues ​​() –

1

No sé si incluir esto en mi pregunta o como respuesta. El problema es que no es LA respuesta, pero es la respuesta que funciona para mí.

lo que he descubierto, por casualidad al intentar otra cosa, es que si sólo wodge sobre el extremo de una cuerda, consigo lo que quiero:

throw new Exception("EnumInterpreter returns empty string for enumVal=" + enumVal); 
//EnumInterpreter returns empty string for enumVal=3720116125 

De hecho, me simplificado a int en mi pregunta , el tipo de datos real es uint (en esta instancia particular). Afortunadamente, dado que en realidad solo quería la cuerda, no tengo que preocuparme por eso.

No estoy seguro de cuál de las otras tres respuestas es 'correcto', por lo que voto de distancia ...

-3

Por qué no analiza la enumeración en una cadena y devuelven el valor de enumeración real?

public enum MyEnum { Flower = 1, Tree = 2, Animal = 3 }; 

string name = MyEnum.Flower.ToString(); // returns "Flower" 

creo .ToString() es obsoleto y no estoy seguro acerca de la nueva manera de hacerlo. ¿Pensaría que la representación enum real sería más útil que la int?

+1

Porque en el contexto del código en cuestión, no tengo acceso a la enumeración. – Benjol

+2

Solo una sobrecarga de '.ToString()' está actualmente en desuso - el intellisense es bastante engañoso en ese sentido. – tomfanning

+0

"¿Por qué no analizar la enumeración de una cadena y devolver el valor real de la enumeración?" - El Int32 IS subyacente es el valor de enum real. – bubbleking

4

probar esto ..

m_EnumInterpreter ((int) (objeto) enumVal);

0

Entiendo que probablemente esta no sea la solución a su problema exacto, pero solo quiero publicar cómo resolví esto para una API en particular que estaba usando.

int result = (int) (ActualEnumType) MethodThatReturnsSystemEnumType(arg1, arg2); 

Espero que sea de ayuda para alguien. Doble lanzamiento FTW.

Cuestiones relacionadas