Convert.ChangeType and conversion to enums?

I got the Int16 value from the database and must convert it to an enum type. Unfortunately, this is done in a code layer that knows very little about objects, except that it can be assembled through reflection.

Thus, he finishes calling Convert.ChangeType , which fails with an invalid exception exception.

I found what I consider to be a smelly workaround, for example:

 String name = Enum.GetName(destinationType, value); Object enumValue = Enum.Parse(destinationType, name, false); 

Is there a better way, so I donโ€™t have to navigate this String operation?

Here's a short but complete program that you can use if someone needs to experiment:

 using System; public class MyClass { public enum DummyEnum { Value0, Value1 } public static void Main() { Int16 value = 1; Type destinationType = typeof(DummyEnum); String name = Enum.GetName(destinationType, value); Object enumValue = Enum.Parse(destinationType, name, false); Console.WriteLine("" + value + " = " + enumValue); } } 
+52
enums c #
Feb 03 '09 at 13:28
source share
3 answers

Enum.ToObject(.... is what you are looking for!

FROM#

 StringComparison enumValue = (StringComparison)Enum.ToObject(typeof(StringComparison), 5); 

Vb.net

 Dim enumValue As StringComparison = CType([Enum].ToObject(GetType(StringComparison), 5), StringComparison) 

If you do a lot of Enum conversions, try using the following class, it will save you a lot of code.

 public class Enum<EnumType> where EnumType : struct, IConvertible { /// <summary> /// Retrieves an array of the values of the constants in a specified enumeration. /// </summary> /// <returns></returns> /// <remarks></remarks> public static EnumType[] GetValues() { return (EnumType[])Enum.GetValues(typeof(EnumType)); } /// <summary> /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object. /// </summary> /// <param name="name"></param> /// <returns></returns> /// <remarks></remarks> public static EnumType Parse(string name) { return (EnumType)Enum.Parse(typeof(EnumType), name); } /// <summary> /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object. /// </summary> /// <param name="name"></param> /// <param name="ignoreCase"></param> /// <returns></returns> /// <remarks></remarks> public static EnumType Parse(string name, bool ignoreCase) { return (EnumType)Enum.Parse(typeof(EnumType), name, ignoreCase); } /// <summary> /// Converts the specified object with an integer value to an enumeration member. /// </summary> /// <param name="value"></param> /// <returns></returns> /// <remarks></remarks> public static EnumType ToObject(object value) { return (EnumType)Enum.ToObject(typeof(EnumType), value); } } 

Now instead of writing (StringComparison)Enum.ToObject(typeof(StringComparison), 5); you can simply write Enum<StringComparison>.ToObject(5); .

+73
03 Feb '09 at 13:41
source share

Based on @Peter's answer, here is a method to convert Nullable<int> to Enum :

 public static class EnumUtils { public static bool TryParse<TEnum>(int? value, out TEnum result) where TEnum: struct, IConvertible { if(!value.HasValue || !Enum.IsDefined(typeof(TEnum), value)){ result = default(TEnum); return false; } result = (TEnum)Enum.ToObject(typeof(TEnum), value); return true; } } 

Using EnumUtils.TryParse<YourEnumType>(someNumber, out result) becomes useful for many scenarios. For example, the WebApi Controller in Asp.NET has no default protection against invalid Enum settings. Asp.NET will use the default(YourEnumType) value default(YourEnumType) , even if some skip null , -1000 , 500000 , "garbage string" or completely ignore the parameter. Moreover, ModelState will act in all of these cases, so one solution is to use the int? type int? with custom validation

 public class MyApiController: Controller { [HttpGet] public IActionResult Get(int? myEnumParam){ MyEnumType myEnumParamParsed; if(!EnumUtils.TryParse<MyEnumType>(myEnumParam, out myEnumParamParsed)){ return BadRequest($"Error: parameter '{nameof(myEnumParam)}' is not specified or incorrect"); } return this.Get(washingServiceTypeParsed); } private IActionResult Get(MyEnumType myEnumParam){ // here we can guarantee that myEnumParam is valid } 
0
Jan 21 '17 at 13:58 on
source share

If you store Enum in a DataTable but donโ€™t know which column is an enum and which is the / int string, you can access this value as follows:

 foreach (DataRow dataRow in myDataTable.Rows) { Trace.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-="); foreach (DataColumn dataCol in myDataTable.Columns) { object v = dataRow[dataCol]; Type t = dataCol.DataType; bool e = false; if (t.IsEnum) e = true; Trace.WriteLine((dataCol.ColumnName + ":").PadRight(30) + (e ? Enum.ToObject(t, v) : v)); } } 
0
Jul 28 '17 at 14:12
source share



All Articles