I'm sure this is fairly trivial but I can't get it right.
public static string DoSomething(this Enum value)
{
if (!Enum.IsDefined(value.GetType(), value))
{
// not a valid value, assume default value
value = default(value.GetType());
}
// ... do some other stuff
}
The line value = default(value.GetType());
doesn't compile, but hopefully you can see what I'm attempting. I need to set the Enum param to the default value of it's own type.
I'm not really sure what you're trying to do here, but a version of the 'default' line which does compile is this:
value = (Enum)Enum.GetValues(value.GetType()).GetValue(0);
Or, even cleaner (from Paw, in the comments, thanks):
value = (Enum) Enum.ToObject(value.GetType(), 0);
This second version does only work properly if you know the enum's first element has a value of zero.
You actually could do what Paw is suggesting, even with a generic constraint, if you could move this method to its own class:
public abstract class Helper<T>
{
public static string DoSomething<TEnum>(TEnum value) where TEnum: struct, T
{
if (!Enum.IsDefined(typeof(TEnum), value))
{
value = default(TEnum);
}
// ... do some other stuff
// just to get code to compile
return value.ToString();
}
}
public class EnumHelper : Helper<Enum> { }
Then you would do, for example:
MyEnum x = MyEnum.SomeValue;
MyEnum y = (MyEnum)100; // Let's say this is undefined.
EnumHelper.DoSomething(x); // generic type of MyEnum can be inferred
EnumHelper.DoSomething(y); // same here
As Konrad Rudolph points out in a comment, default(TEnum)
in the above code will evaluate to 0, regardless of whether or not a value is defined for 0 for the given TEnum
type. If that's not what you want, Will's answer provides certainly the easiest way of getting the first defined value ((TEnum)Enum.GetValues(typeof(TEnum)).GetValue(0)
).
On the other hand, if you want to take this to the extreme, and cache the result so that you don't always have to box it, you could do that:
public abstract class Helper<T>
{
static Dictionary<Type, T> s_defaults = new Dictionary<Type, T>();
public static string DoSomething<TEnum>(TEnum value) where TEnum: struct, T
{
if (!Enum.IsDefined(typeof(TEnum), value))
{
value = GetDefault<TEnum>();
}
// ... do some other stuff
// just to get code to compile
return value.ToString();
}
public static TEnum GetDefault<TEnum>() where TEnum : struct, T
{
T definedDefault;
if (!s_defaults.TryGetValue(typeof(TEnum), out definedDefault))
{
// This is the only time you'll have to box the defined default.
definedDefault = (T)Enum.GetValues(typeof(TEnum)).GetValue(0);
s_defaults[typeof(TEnum)] = definedDefault;
}
// Every subsequent call to GetDefault on the same TEnum type
// will unbox the same object.
return (TEnum)definedDefault;
}
}
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