Да, если тип поддержки enum
не int
, например:
public enum X : long
{
A,
B,
C
}
Это бросит. Это связано с тем, что значения enum
являются полями как object
, и вы не можете привести «object» к «int», если только содержащееся значение не является «int».
Вы можете смягчить это, выполнив Convert.ToInt32()
, который будет работать для всех типов поддержки int
или меньше:
static void foo(Type typeEnum)
{
if (typeEnum.IsEnum)
{
foreach (var enumVal in Enum.GetValues(typeEnum))
{
var _val = Convert.ToInt32(enumVal);
}
}
}
Или, если вы хотите принять int
и просто быть более безопасным, вы можете проверить базовый тип enum
, например:
if (Enum.GetUnderlyingType(typeEnum) != typeof(int))
{
throw new ArgumentException("This method only accepts int enums.");
}
В качестве альтернативы вы можете принять тип long
, если он подписан, или ulong
, если он не подписан (вы можете иметь отрицательные значения enum
, но, как правило, реже):
static void foo(Type typeEnum)
{
if (typeEnum.IsEnum)
{
foreach (var enumVal in Enum.GetValues(typeEnum))
{
var _val = Convert.ToInt64(enumVal);
}
}
}
Вот почему, вероятно, безопаснее делать некоторые предположения и проверять их по вызову. Все, что вы делаете для распаковки значения, может быть выброшено или переполнено.
Вы могли бы даже пойти универсально и указать пользователю тип, который он хочет получить:
static IEnumerable<ToType> foo<ToType>(Type typeEnum)
{
if (typeEnum.IsEnum)
{
foreach (var enumVal in Enum.GetValues(typeEnum))
{
yield return (ToType)Convert.ChangeType(enumVal, typeof(ToType));
}
}
}
Так что вы можете вызвать это:
IEnumerable<int> values foo<int>(typeof(YourEnum));
Тогда, если они получают исключение, они должны указать правильный тип размера ...