En .NET Core y .NET> 4 hay un método de análisis genérico :
Enum.TryParse("Active", out StatusEnum myStatus);
Esto también incluye las nuevas out
variables en línea de C # 7 , por lo que realiza la conversión de prueba, conversión al tipo de enumeración explícita e inicializa + llena la myStatus
variable.
Si tiene acceso a C # 7 y al último .NET, esta es la mejor manera.
Respuesta original
En .NET es bastante feo (hasta 4 o superior):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
Tiendo a simplificar esto con:
public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
Entonces puedo hacer:
StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");
Una opción sugerida en los comentarios es agregar una extensión, que es lo suficientemente simple:
public static T ToEnum<T>(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();
Finalmente, es posible que desee tener una enumeración predeterminada para usar si la cadena no se puede analizar:
public static T ToEnum<T>(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
T result;
return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}
Lo que hace que esta sea la llamada:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
Sin embargo, sería cuidadoso al agregar un método de extensión como este, string
ya que (sin control de espacio de nombres) aparecerá en todas las instancias de string
si tienen una enumeración o no (por 1234.ToString().ToEnum(StatusEnum.None)
lo que sería válido pero sin sentido). A menudo es mejor evitar abarrotar las clases principales de Microsoft con métodos adicionales que solo se aplican en contextos muy específicos, a menos que todo su equipo de desarrollo comprenda muy bien lo que hacen esas extensiones.
Uso
Enum.TryParse<T>(String, T)
(≥ .NET 4.0):Se puede simplificar aún más con la alineación de tipos de parámetros de C # 7.0 :
fuente
Parse
lanza excepciones explicativas de lo que salió mal con la conversión (el valor eranull
, vacío o sin constante de enumeración correspondiente), que es mucho mejor queTryParse
el valor de retorno booleano (que suprime el error concreto)var result = Enum.TryParse<System.DayOfWeek>("55", out var parsedEnum);
Tenga en cuenta que el rendimiento de
Enum.Parse()
es horrible, ya que se implementa a través de la reflexión. (Lo mismo es cierto de loEnum.ToString
que va para otro lado).Si necesita convertir cadenas a Enums en código sensible al rendimiento, su mejor opción es crear un
Dictionary<String,YourEnum>
inicio y utilizarlo para realizar sus conversiones.fuente
Estás buscando Enum .
fuente
Puede usar métodos de extensión ahora:
Y puede llamarlos por el siguiente código (aquí,
FilterType
es un tipo de enumeración):fuente
Entonces, si tuviera una enumeración llamada estado de ánimo, se vería así:
fuente
TENER CUIDADO:
Enum.(Try)Parse()
acepta múltiples argumentos separados por comas y los combina con binarios 'o'|
. No puede desactivar esto y, en mi opinión, casi nunca lo quiere.Incluso si
Three
no se definió,x
todavía obtendría el valor int3
. Eso es aún peor: ¡Enum.Parse () puede darle un valor que ni siquiera está definido para la enumeración!No quisiera experimentar las consecuencias de los usuarios, voluntaria o involuntariamente, que desencadenan este comportamiento.
Además, como lo mencionaron otros, el rendimiento es menos que ideal para grandes enumeraciones, es decir, lineal en la cantidad de valores posibles.
Sugiero lo siguiente:
fuente
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'
. Significa que puede configurar sus valores de enumeración como potencias de 2 y tiene una manera muy fácil de analizar múltiples banderas booleanas, por ejemplo. "UseSSL, NoRetries, Sync". De hecho, eso es probablemente para lo que fue diseñado.Enum.Parse es tu amigo:
fuente
Puede ampliar la respuesta aceptada con un valor predeterminado para evitar excepciones:
Entonces lo llamas así:
Si el valor predeterminado no es una enumeración, Enum. TryParse fallará y generará una excepción que se detecte.
Después de años de usar esta función en nuestro código en muchos lugares, ¡tal vez sea bueno agregar la información de que esta operación cuesta rendimiento!
fuente
defaultValue
tipo de retorno y el método son ambos de tipoT
. Si los tipos son diferentes, recibirá un error de tiempo de compilación: "no se puede convertir de 'ConsoleApp1.Size' a 'ConsoleApp1.Color'" o cualesquiera que sean sus tipos.No pudimos asumir una entrada perfectamente válida, y seguimos con esta variación de la respuesta de @ Keith:
fuente
fuente
Analiza cadenas a TEnum sin try / catch y sin el método TryParse () de .NET 4.5
fuente
Código super simple usando TryParse:
fuente
Me gusta la solución del método de extensión.
Aquí debajo mi implementación con pruebas.
fuente
==================== Un programa completo ====================
fuente
Utilicé class (versión fuertemente tipada de Enum con análisis y mejoras de rendimiento). Lo encontré en GitHub, y también debería funcionar para .NET 3.5. Tiene algo de memoria por encima ya que almacena un diccionario.
La publicación de blog es Enums: mejor sintaxis, rendimiento mejorado y TryParse en NET 3.5 .
Y código: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs
fuente
Para el rendimiento, esto podría ayudar:
fuente
Encontré que aquí no se consideró el caso con valores enum que tienen el valor EnumMember. Así que, aquí vamos:
Y ejemplo de esa enumeración:
fuente
Debe usar Enum.Parse para obtener el valor del objeto de Enum, después de eso debe cambiar el valor del objeto a un valor de enumeración específico. La conversión al valor de enumeración se puede hacer utilizando Convert.ChangeType. Por favor, eche un vistazo al siguiente fragmento de código
fuente
Prueba esta muestra:
En este ejemplo, puede enviar cada cadena y establecer su
Enum
. SiEnum
tenía datos que deseaba, devuélvalos como suEnum
tipo.fuente
newModel
en cada línea, por lo que si contiene guiones, no se reemplazará. Además, no tiene que verificar si la cadena contiene algo, simplemente puede llamar deReplace
todos modos:var newModel = model.Replace("-", "").Replace(" ", "");
No estoy seguro de cuándo se agregó esto, pero en la clase Enum ahora hay un
Parse<TEnum>(stringValue)
Usado así con el ejemplo en cuestión:
var MyStatus = Enum.Parse<StatusEnum >("Active")
o ignorando la carcasa por:
var MyStatus = Enum.Parse<StatusEnum >("active", true)
Aquí están los métodos descompilados que usa:
fuente
fuente
fuente
Si el nombre de la propiedad es diferente del que desea llamarlo (es decir, diferencias de idioma), puede hacer lo siguiente:
MyType.cs
EnumExtensions.cs
Program.cs
fuente