I have a simple Enum
public enum TestEnum
{
TestOne = 3,
TestTwo = 4
}
var testing = TestEnum.TestOne;
And I want to retrieve
You can use the System.Enum helpers:
System.Type enumType = typeof(TestEnum);
System.Type enumUnderlyingType = System.Enum.GetUnderlyingType(enumType);
System.Array enumValues = System.Enum.GetValues(enumType);
for (int i=0; i < enumValues.Length; i++)
{
// Retrieve the value of the ith enum item.
object value = enumValues.GetValue(i);
// Convert the value to its underlying type (int, byte, long, ...)
object underlyingValue = System.Convert.ChangeType(value, enumUnderlyingType);
System.Console.WriteLine(underlyingValue);
}
Outputs
3
4
Just simple.
var value = propertyInfo.GetValue(obj); // this return TestOne or TestTwo
var enumValue = Convert.ChangeType(value, typeof(int)); // this return 3 or 4
Great question Mat.
The scenario of the question is this:
You have some unknown enum type and some unknown value of that type and you want to get the underlying numeric value of that unknown value.
This is the one-line way of doing this using reflection:
object underlyingValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()));
If value happens to be TestEnum.TestTwo
, then value.GetType()
would be equal to typeof(TestEnum)
, Enum.GetUnderlyingType(value.GetType())
would be equal to typeof(int)
and value would be 3 (boxed; see http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx for more details about boxing and unboxing values).
Why would one ever need to write such code? In my case, I have a routine that copies values from a viewmodel to a model. I use this in all my handlers in an ASP.NET MVC project as part of a very clean and elegant architecture for writing handlers that do not have the security problems the handlers generated by the Microsoft templates do.
The model is generated by the Entity Framework from the database and it contains a field of type int. The viewmodel has a field of some enum type, let's call it RecordStatus, which I have defined elsewhere in my project. I decided to support enums fully in my framework. But now there is a mismatch between the type of the field in the model and the type of the corresponding field in the viewmodel. My code detects this and converts the enum to an int using the code similar to the one-liner given above.
In my case, the problem was MyEnum not been found due to a + sign getting type from assembly (line 2):
var dll = System.Reflection.Assembly.LoadFile("pathToDll");
Type myEnum = dll.GetType("namespace+MyEnum");
System.Array myEnumValues = System.Enum.GetValues(myEnum);
Try the following:
System.Array enumValues = System.Enum.GetValues(typeof(MyEnum));
Type underlyingType = System.Enum.GetUnderlyingType(MyEnum);
foreach (object enumValue in enumValues)
System.Console.WriteLine(String.Format("{0}",Convert.ChangeType(enumValue ,underlyingType)));
You can use the Gethashkey function to get the value of enum with an unknown type.
Enum.Parse(enumType, enumvalue).GetHashCode();
More details
Getting enum type dynamically
private static Type GetEnumType(string enumName)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var type = assembly.GetType(enumName);
if (type == null)
continue;
if (type.IsEnum)
return type;
}
return null;
}
Reading enum values
Enum.GetValues(enumType);
I hope it helps someone!