una texto que español enumeracion enum clase c# enums

c# - texto - convertir una enumeración en otro tipo de enumeración



enum c# español (11)

Tengo una enumeración de, por ejemplo, '' Gender '' ( Male =0 , Female =1 ) y tengo otra enumeración de un servicio que tiene su propia Enum de género ( Male =0 , Female =1, Unknown =2 )

Mi pregunta es ¿cómo puedo escribir algo rápido y agradable para convertir de su enum al mío?


Aquí hay una versión del método de extensión si alguien está interesado

public static TEnum ConvertEnum<TEnum >(this Enum source) { return (TEnum)Enum.Parse(typeof(TEnum), source.ToString(), true); } // Usage NewEnumType newEnum = oldEnumVar.ConvertEnum<NewEnumType>();


Dado el Enum1 value = ... , entonces si quiere decir por nombre:

Enum2 value2 = (Enum2) Enum.Parse(typeof(Enum2), value.ToString());

Si quiere decir valor numérico, por lo general solo puede enviar:

Enum2 value2 = (Enum2)value;

(con el reparto, es posible que desee utilizar Enum.IsDefined para verificar valores válidos, sin embargo)


El uso de un método de extensión funciona bastante bien, al usar los dos métodos de conversión sugeridos por Nate:

public static class TheirGenderExtensions { public static MyGender ToMyGender(this TheirGender value) { // insert switch statement here } } public static class MyGenderExtensions { public static TheirGender ToTheirGender(this MyGender value) { // insert switch statement here } }

Obviamente, no es necesario utilizar clases separadas si no lo desea. Mi preferencia es mantener los métodos de extensión agrupados por las clases / estructuras / enumeraciones a las que se aplican.


Hace un tiempo escribí un conjunto de métodos de extensión que funcionan para varios tipos diferentes de Enum . Uno en particular funciona para lo que está intentando lograr y maneja Enum s con FlagsAttribute y Enum s con diferentes tipos subyacentes.

public static tEnum SetFlags<tEnum>(this Enum e, tEnum flags, bool set, bool typeCheck = true) where tEnum : IComparable { if (typeCheck) { if (e.GetType() != flags.GetType()) throw new ArgumentException("Argument is not the same type as this instance.", "flags"); } var flagsUnderlyingType = Enum.GetUnderlyingType(typeof(tEnum)); var firstNum = Convert.ToUInt32(e); var secondNum = Convert.ToUInt32(flags); if (set) firstNum |= secondNum; else firstNum &= ~secondNum; var newValue = (tEnum)Convert.ChangeType(firstNum, flagsUnderlyingType); if (!typeCheck) { var values = Enum.GetValues(typeof(tEnum)); var lastValue = (tEnum)values.GetValue(values.Length - 1); if (newValue.CompareTo(lastValue) > 0) return lastValue; } return newValue; }

Desde allí, puede agregar otros métodos de extensión más específicos.

public static tEnum AddFlags<tEnum>(this Enum e, tEnum flags) where tEnum : IComparable { SetFlags(e, flags, true); } public static tEnum RemoveFlags<tEnum>(this Enum e, tEnum flags) where tEnum : IComparable { SetFlags(e, flags, false); }

Éste cambiará los tipos de Enum como lo intentas hacer.

public static tEnum ChangeType<tEnum>(this Enum e) where tEnum : IComparable { return SetFlags(e, default(tEnum), true, false); }

Tenga en cuenta, sin embargo, que PUEDE convertir cualquier Enum y cualquier otro Enum utilizando este método, incluso aquellos que no tienen banderas. Por ejemplo:

public enum Turtle { None = 0, Pink, Green, Blue, Black, Yellow } [Flags] public enum WriteAccess : short { None = 0, Read = 1, Write = 2, ReadWrite = 3 } static void Main(string[] args) { WriteAccess access = WriteAccess.ReadWrite; Turtle turtle = access.ChangeType<Turtle>(); }

La turtle variable tendrá un valor de Turtle.Blue .

Sin embargo, existe seguridad a partir de los valores Enum indefinidos que utilizan este método. Por ejemplo:

static void Main(string[] args) { Turtle turtle = Turtle.Yellow; WriteAccess access = turtle.ChangeType<WriteAccess>(); }

En este caso, el access se establecerá en WriteAccess.ReadWrite , ya que WriteAccess Enum tiene un valor máximo de 3.

Otro efecto secundario de mezclar Enum s con FlagsAttribute y aquellos sin él es que el proceso de conversión no dará como resultado una coincidencia de 1 a 1 entre sus valores.

public enum Letters { None = 0, A, B, C, D, E, F, G, H } [Flags] public enum Flavors { None = 0, Cherry = 1, Grape = 2, Orange = 4, Peach = 8 } static void Main(string[] args) { Flavors flavors = Flavors.Peach; Letters letters = flavors.ChangeType<Letters>(); }

En este caso, las letters tendrán un valor de Letters.H lugar de Letters.D , ya que el valor de respaldo de Flavors.Peach es 8. Además, una conversión de Flavors.Cherry | Flavors.Grape Flavors.Cherry | Flavors.Grape to Letters produciría Letters.C , que puede parecer poco intuitivo.


Para ser minucioso, normalmente creo un par de funciones, una que toma Enum 1 y devuelve Enum 2 y otra que toma Enum 2 y devuelve Enum 1. Cada una consta de una asignación de mayúsculas y minúsculas a las salidas y el caso predeterminado arroja una excepción con una mensaje quejándose de un valor inesperado.

En este caso particular, podría aprovechar el hecho de que los valores enteros de Hombre y Mujer son los mismos, pero evitaría eso ya que es hackish y está sujeto a rotura si cualquiera de las enum cambia en el futuro.


Podría escribir un método de extensión genérico simple como este

public static T ConvertTo<T>(this object value) where T : struct,IConvertible { var sourceType = value.GetType(); if (!sourceType.IsEnum) throw new ArgumentException("Source type is not enum"); if (!typeof(T).IsEnum) throw new ArgumentException("Destination type is not enum"); return (T)Enum.Parse(typeof(T), value.ToString()); }


Puede usar ToString () para convertir la primera enumeración en su nombre, y luego Enum.Parse () para convertir la cadena nuevamente en la otra Enum. Esto lanzará una excepción si el valor no es soportado por la enumeración de destino (es decir, para un valor "Desconocido")


Sé que es una pregunta antigua y tengo muchas respuestas. Sin embargo, considero que usar una declaración de cambio como en la respuesta aceptada es algo engorroso, así que aquí están mis 2 centavos:

Mi método favorito personal es usar un diccionario, donde la clave es la fuente enum y el valor es la enumeración objetivo, por lo que en el caso presentado en la pregunta, mi código se vería así:

var genderTranslator = new Dictionary<TheirGender, MyGender>(); genderTranslator.Add(TheirGender.Male, MyGender.Male); genderTranslator.Add(TheirGender.Female, MyGender.Female); genderTranslator.Add(TheirGender.Unknown, MyGender.Unknown); // translate their to mine var myValue = genderTranslator[TheirValue]; // translate mine to their var TheirValue = genderTranslator .FirstOrDefault(x => x.Value == myValue).Key;;

Por supuesto, esto puede ser envuelto en una clase estática y ser utilizado como un método de extensión:

public static class EnumTranslator { private static Dictionary<TheirGender, MyGender> GenderTranslator = InitializeGenderTranslator(); private static Dictionary<TheirGender, MyGender> InitializeGenderTranslator() { var translator = new Dictionary<TheirGender, MyGender>(); translator.Add(TheirGender.Male, MyGender.Male); translator.Add(TheirGender.Female, MyGender.Female); translator.Add(TheirGender.Unknown, MyGender.Unknown); return translator; } public static MyGender Translate(this TheirGender theirValue) { return GenderTranslator[theirValue]; } public static TheirGender Translate(this MyGender myValue) { return GenderTranslator.FirstOrDefault(x => x.Value == myValue).Key; } }


Si tenemos:

enum Gender { M = 0, F = 1, U = 2 }

y

enum Gender2 { Male = 0, Female = 1, Unknown = 2 }

Podemos hacerlo con seguridad

var gender = Gender.M; var gender2 = (Gender2)(int)gender;

O incluso

var enumOfGender2Type = (Gender2)0;

Si desea cubrir el caso donde una enumeración en el lado derecho del signo ''='' tiene más valores que la enumeración en el lado izquierdo, tendrá que escribir su propio método / diccionario para cubrirlo como otros sugirieron.


Simplemente eche uno a int y luego vuélvalo a la otra enumeración (teniendo en cuenta que desea que el mapeo se realice en función del valor):

Gender2 gender2 = (Gender2)((int)gender1);


podrías escribir una función simple como la siguiente:

public static MyGender ConvertTo(TheirGender theirGender) { switch(theirGender) { case TheirGender.Male: break;//return male case TheirGender.Female: break;//return female case TheirGender.Unknown: break;//return whatever } }