Вы на самом деле могли бы сделать то, что Paw is suggesting, даже с общим ограничением, если вы могли бы переместить этот метод к своему собственному классу:
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
. Если это не то, что вы хотите, Will's answer обеспечивает, безусловно, самый простой способ получения первого значения ((TEnum)Enum.GetValues(typeof(TEnum)).GetValue(0)
).
С другой стороны, если вы хотите принять это к крайней и кэшировать результат, так что вы не всегда должны боксировать, вы могли бы сделать это:
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;
}
}
Как может вы даже называете этот метод без определения значения в перечислении того же типа, что и «значение»? –
@Paw, вот как работает enum. Вы можете сохранить любое значение int в int enum, независимо от того, определено оно или нет. – fearofawhackplanet
@fearofawhackplanet, я просто пытаюсь понять, что вы пытаетесь сделать. Если вы хотите преобразовать int в перечисление или, может быть, строку в перечисление? –