Вы действительно могли бы сделать то, что Paw предлагает , даже с общим ограничением, если бы вы могли переместить этот метод в его собственный класс:
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> { }
Тогда вы бы сделали, дляпример:
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
Как отмечает Конрад Рудольф в комментарии, default(TEnum)
в приведенном выше коде будет иметь значение 0, независимо от того, определено ли значение 0 для данного типа TEnum
,Если это не то, что вам нужно, ответ Уилла , безусловно, обеспечивает самый простой способ получения первого определенного значения ((TEnum)Enum.GetValues(typeof(TEnum)).GetValue(0)
).
С другой стороны, есливы хотите принять это к extreme и кэшировать результат, чтобы вам не всегда приходилось его упаковывать, вы можете сделать это:
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;
}
}