Convierte Enum a Cadena

¿Cuál es la forma preferida de convertir un Enum a una cadena en .NET 3.5?

  • Enum.GetName
  • Enum.Format
  • Encadenar

¿Por qué debería preferir uno de estos sobre los demás? ¿Uno se desempeña mejor?

A partir de C # 6 la mejor manera de obtener el nombre de una enumeración es el nuevo nameof operador:

 nameof(MyEnum.EnumValue); // Ouputs > "EnumValue" 

Esto funciona en tiempo de comstackción, con la enumeración reemplazada por la cadena en el resultado comstackdo, que a su vez significa que es la forma más rápida posible.

Cualquier uso de los nombres enum interfiere con la ofuscación del código, si considera que la ofuscación de los nombres enum es útil o importante, esa es probablemente otra pregunta.

Funciona para nuestro proyecto …

 public static String convertToString(this Enum eff) { return Enum.GetName(eff.GetType(), eff); } public static EnumType converToEnum(this String enumValue) { return (EnumType) Enum.Parse(typeof(EnumType), enumValue); } 

Todos estos terminan internamente llamando a un método llamado InternalGetValueAsString . La diferencia entre ToString y GetName sería que GetName tiene que verificar algunas cosas primero:

  1. El tipo que ingresó no es nulo.
  2. El tipo que ingresó es, de hecho, una enumeración.
  3. El valor que pasaste no es nulo.
  4. El valor que ha pasado es de un tipo que una enumeración puede usar realmente como su tipo subyacente o del tipo de la enumeración en sí. Utiliza GetType en el valor para verificar esto.

.ToString no tiene que preocuparse por ninguno de estos problemas anteriores, ya que se .ToString en una instancia de la clase en sí, y no en una versión aprobada, por lo tanto, debido a que el método .ToString no tiene los mismos problemas de verificación que los métodos estáticos, concluiría que .ToString es la forma más rápida de obtener el valor como una cadena.

En mis pruebas, Enum.GetName fue más rápido y con un margen decente. Internally ToString llama a Enum.GetName . Desde el origen de .NET 4.0, lo esencial:

 public override String ToString() { return Enum.InternalFormat((RuntimeType)GetType(), GetValue()); } private static String InternalFormat(RuntimeType eT, Object value) { if (!eT.IsDefined(typeof(System.FlagsAttribute), false)) { String retval = GetName(eT, value); //<== the one if (retval == null) return value.ToString(); else return retval; } else { return InternalFlagsFormat(eT, value); } } 

No puedo decir que ese sea el motivo seguro, pero las pruebas dicen que una es más rápida que la otra. Ambas llamadas implican el boxeo (de hecho, son llamadas de reflexión, esencialmente estás recuperando nombres de campo) y pueden ser lentas para tu gusto.

Configuración de la prueba : enum con 8 valores, no. de iteraciones = 1000000

Resultado : Enum.GetName => 700 ms, ToString => 2000 ms

Si la velocidad no es notable, no me importaría y usaría ToString ya que ofrece una llamada mucho más ToString . Contraste

 Enum.GetName(typeof(Bla), value) 

con

 value.ToString() 

Lo mejor que puedo encontrar es esta pregunta no relacionada en MSDN , que contiene un fragmento de XML que responde a esta pregunta. Cualquiera de estos métodos comparte el mismo defecto: llaman a enum.toString() , que no funciona correctamente cuando se usa Dotfuscation . Otras preocupaciones parecen estar relacionadas con el boxeo indirecto (GetName y Format). Lamentablemente, no puedo encontrar ningún motivo de rendimiento para usar cualquiera de los anteriores.

Parafraseando desde el fragmento xml ,

Pasar una enumeración enmarcada a cadena. El formato () o cualquier otra función puede dar como resultado que se enum.ToString() a enum.ToString() . Esto causará problemas al Dotfuscating. No debe usar enum.ToString() , enum.GetNames() , enum.GetName() , enum.Format() o enum.Parse() para convertir una enumeración en una cadena. En su lugar, use una statement de cambio, y también internacionalice los nombres si es necesario.

Enum.GetName()

Format() es realmente solo un contenedor alrededor de GetName() con alguna funcionalidad de formateo (o InternalGetValueAsString() para ser exactos). ToString() es prácticamente lo mismo que Format() . Creo que GetName() es la mejor opción, ya que es totalmente obvio lo que hace para cualquiera que lea la fuente.

Enum.GetName (…)

Este es el método más elegante que está destinado para ello.

 var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue); 

Aunque no veo ningún problema con llamar .ToString() ya que es simplemente más corto.

 var enumValueString = MyEnum.MyValue.ToString(); 

Con la nueva syntax C # 6 puedes usar:

 nameof(MyEnum.MyValue) 

Creo un método de extensión “Descripción” y lo adjunto a la enumeración para que pueda obtener nombres verdaderamente fáciles de usar que incluyen espacios y envoltura. Nunca me ha gustado usar el valor enum como texto visualizable porque es algo que los desarrolladores usamos para crear un código más legible. No está destinado a fines de visualización de interfaz de usuario. Quiero poder cambiar la UI sin tener que pasar y cambiar enumeraciones por todas partes.

No sé cuál es el método “preferido” (pregunte a 100 personas y obtenga 100 opiniones diferentes), pero haga lo más simple y lo que funcione. GetName funciona, pero requiere muchas más teclas. ToString() parece hacer el trabajo muy bien.

Esto también funcionaría.

  List names = Enum.GetNames(typeof(MyEnum)).ToList(); 

Para los aficionados a VB:

 EnumStringValue = System.Enum.GetName(GetType(MyEnum), MyEnumValue) 

Simple: nombres enum en una lista:

 List NameList = Enum.GetNames(typeof(YourEnumName)).Cast().ToList()