I have an object. Usually it is either long
or string
, so to simplify the code let's assume just that.
I have to create a method that tries to convert this object to a provided enum. So:
public object ToEnum(Type enumType, object value)
{
if(enumType.IsEnum)
{
if(Enum.IsDefined(enumType, value))
{
var val = Enum.Parse(enumType, (string)value);
return val;
}
}
return null;
}
With strings it works well. With numbers it causes problems, because a default underlying type for enum is int
, not long
and IsDefined
throws an ArgumentException
.
Of course I can do many checks, conversions or try-catches.
What I want is to have a clean and small code for that. Any ideas how to make it readable and simple?
It feels to me like you only actually want to handle three cases:
I believe this will do what you want for valid input:
public object ToEnum(Type enumType, object value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (enumType == null)
{
throw new ArgumentNullException("type");
}
if (!enumType.IsEnum)
{
return false;
}
string valueString = value as string;
if (valueString != null)
{
return Enum.IsDefined(enumType, value) ? Enum.Parse(enumType, valueString) : null;
}
if (value.GetType() == enumType)
{
return value;
}
// This appears to handle longs etc
return Enum.ToObject(enumType, value);
}
However, that will return a value of the right type even for undefined values. If you don't want that, change the last part to:
object candidate = Enum.ToObject(enumType, value);
return Enum.IsDefined(enumType, candidate) ? candidate : null;
Also, this will still throw an exception if you pass in a floating point number, or something like that. If you don't want that behaviour, you'll need to have a set of all the types you do want to accept, and check against that first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With