Как конфертировать из System.Enum в base integer?
Я хотел бы создать общий метод преобразования любого производного типа System.Enum в соответствующее целочисленное значение без литья и, желательно, без синтаксического анализа строки.
Например, я хочу что-то вроде этого:
// Trivial example, not actually what I'm doing.
class Converter
{
int ToInteger(System.Enum anEnum)
{
(int)anEnum;
}
}
Но это не работает. Resharper сообщает, что вы не можете использовать выражение типа "System.Enum" для ввода "int".
Теперь я придумал это решение, но я предпочел бы иметь что-то более эффективное.
class Converter
{
int ToInteger(System.Enum anEnum)
{
return int.Parse(anEnum.ToString("d"));
}
}
Любые предложения?
Ответы
Ответ 1
Если вы не хотите использовать,
Convert.ToInt32()
мог сделать трюк.
Прямая трансляция (через (int)enumValue
) невозможна. Обратите внимание, что это также будет "опасно", поскольку перечисление может иметь разные базовые типы (int
, long
, byte
...).
Более формально: System.Enum
не имеет прямого отношения наследования с Int32
(хотя оба они ValueType
s), поэтому явное приведение не может быть правильным в системе типов
Ответ 2
Я получил его для работы, отбрасывая объект, а затем в int:
public static class EnumExtensions
{
public static int ToInt(this Enum enumValue)
{
return (int)((object)enumValue);
}
}
Это уродливо и, вероятно, не самый лучший способ. Я буду продолжать возиться с ним, чтобы увидеть, могу ли я придумать что-то лучшее...
EDIT: собирался опубликовать, что Convert.ToInt32 (enumValue) работает так же хорошо, и заметил, что MartinStettner избил меня.
public static class EnumExtensions
{
public static int ToInt(this Enum enumValue)
{
return Convert.ToInt32(enumValue);
}
}
Тест:
int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday
EDIT 2: В комментариях кто-то сказал, что это работает только в С# 3.0. Я просто тестировал это в VS2005, как это, и он работал:
public static class Helpers
{
public static int ToInt(Enum enumValue)
{
return Convert.ToInt32(enumValue);
}
}
static void Main(string[] args)
{
Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
}
Ответ 3
Зачем вам нужно изобретать колесо с помощью вспомогательного метода? Это совершенно законно, чтобы присвоить значение enum
его базовому типу.
Это меньше печатает, и, на мой взгляд, более читаемо, чтобы использовать...
int x = (int)DayOfWeek.Tuesday;
... а не что-то вроде...
int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();
Ответ 4
Если вам нужно преобразовать любое перечисление в его базовый тип (не все перечисления поддерживаются int
), вы можете использовать:
return System.Convert.ChangeType(
enumValue,
Enum.GetUnderlyingType(enumValue.GetType()));
Ответ 5
Из моего ответа здесь:
Учитывая e
как в:
Enum e = Question.Role;
Затем эти работы:
int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);
Последние два являются уродливыми. Первый должен быть более читабельным, хотя второй - намного быстрее. Или может быть метод расширения - лучший, лучший из обоих миров.
public static int GetIntValue(this Enum e)
{
return e.GetValue<int>();
}
public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
return (T)(object)e;
}
Теперь вы можете позвонить:
e.GetValue<int>(); //or
e.GetIntValue();
Ответ 6
Кастинг от System.Enum
до int
отлично работает для меня (он также находится на MSDN). Возможно, это ошибка Resharper.
Ответ 7
Не забывайте, что сам тип Enum содержит множество статических вспомогательных функций. Если все, что вы хотите сделать, - это преобразовать экземпляр enum в соответствующий ему целочисленный тип, тогда литье, вероятно, является наиболее эффективным способом.
Я думаю, что ReSharper жалуется, потому что Enum не является перечислением какого-либо определенного типа, а сами перечисления производятся из скалярного valueetype, а не Enum. Если вам требуется адаптируемое кастинг в общем виде, я бы сказал, что это может вам хорошо подобрать (обратите внимание, что сам тип перечисления также включен в общий файл:
public static EnumHelpers
{
public static T Convert<T, E>(E enumValue)
{
return (T)enumValue;
}
}
Затем это можно использовать следующим образом:
public enum StopLight: int
{
Red = 1,
Yellow = 2,
Green = 3
}
// ...
int myStoplightColor = EnumHelpers.Convert<int, StopLight>(StopLight.Red);
Я не могу сказать наверняка с головы, но приведенный выше код может даже поддерживаться выводами типа С#, позволяя следующее:
int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red);