Получить значение int из enum в C # - PullRequest
1601 голосов
/ 03 июня 2009

У меня есть класс с именем Questions (множественное число). В этом классе есть перечисление Question (единственное), которое выглядит следующим образом.

public enum Question
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

В классе Questions у меня есть функция get(int foo), которая возвращает объект Questions для этого foo. Есть ли простой способ получить целочисленное значение из перечисления, чтобы я мог сделать что-то вроде Questions.Get(Question.Role)?

Ответы [ 26 ]

2073 голосов
/ 03 июня 2009

Просто приведите enum, например,

int something = (int) Question.Role;

Вышеуказанное будет работать для подавляющего большинства перечислений, которые вы видите в дикой природе, поскольку базовый тип по умолчанию для перечисления int.

Однако, как указывает cecilphillip , перечисления могут иметь различные базовые типы. Если перечисление объявлено как uint, long или ulong, оно должно быть приведено к типу перечисления; например для

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

Вы должны использовать

long something = (long)StarsInMilkyWay.Wolf424B;
276 голосов
/ 09 июля 2010

Поскольку перечисления могут быть любого целочисленного типа (byte, int, short и т. Д.), Более надежным способом получения базового интегрального значения перечисления было бы использование GetTypeCode метод в сочетании с классом Convert:

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

Это должно работать независимо от базового целочисленного типа.

177 голосов
/ 15 июня 2012

Объявите его как статический класс, имеющий открытые константы:

public static class Question
{
    public const int Role = 2;
    public const int ProjectFunding = 3;
    public const int TotalEmployee = 4;
    public const int NumberOfServers = 5;
    public const int TopBusinessConcern = 6;
}

И затем вы можете ссылаться на него как Question.Role, и он всегда будет иметь значение int или как вы его определите.

78 голосов
/ 03 июня 2009
Question question = Question.Role;
int value = (int) question;

приведет к value == 2.

64 голосов
/ 01 декабря 2013

В связанной заметке, если вы хотите получить значение int из System.Enum, тогда задайте 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);

Последние два безобразны. Я предпочитаю первый.

37 голосов
/ 03 июня 2009

Это проще, чем вы думаете - перечисление уже int. Это просто нужно напомнить:

int y = (int)Question.Role;
Console.WriteLine(y); // prints 2
27 голосов
/ 25 сентября 2009

Пример:

public Enum EmpNo
{
    Raj = 1,
    Rahul,
    Priyanka
}

И в коде для получения значения перечисления:

int setempNo = (int)EmpNo.Raj; //This will give setempNo = 1

или

int setempNo = (int)EmpNo.Rahul; //This will give setempNo = 2

Перечисления будут увеличиваться на 1, и вы можете установить начальное значение. Если вы не установите начальное значение, оно будет изначально присвоено как 0.

20 голосов
/ 30 марта 2013

Я недавно отказался от использования перечислений в своем коде, вместо этого вместо использования классов с защищенными конструкторами и предопределенными статическими экземплярами (благодаря Roelof - C # Обеспечение допустимых значений перечисления - Метод будущего ).

В свете вышесказанного, как я теперь подхожу к этому вопросу (включая неявное преобразование в / из int).

public class Question
{
    // Attributes
    protected int index;
    protected string name;
    // Go with a dictionary to enforce unique index
    //protected static readonly ICollection<Question> values = new Collection<Question>();
    protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();

    // Define the "enum" values
    public static readonly Question Role = new Question(2,"Role");
    public static readonly Question ProjectFunding = new Question(3, "Project Funding");
    public static readonly Question TotalEmployee = new Question(4, "Total Employee");
    public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
    public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");

    // Constructors
    protected Question(int index, string name)
    {
        this.index = index;
        this.name = name;
        values.Add(index, this);
    }

    // Easy int conversion
    public static implicit operator int(Question question) =>
        question.index; //nb: if question is null this will return a null pointer exception

    public static implicit operator Question(int index) =>        
        values.TryGetValue(index, out var question) ? question : null;

    // Easy string conversion (also update ToString for the same effect)
    public override string ToString() =>
        this.name;

    public static implicit operator string(Question question) =>
        question?.ToString();

    public static implicit operator Question(string name) =>
        name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));


    // If you specifically want a Get(int x) function (though not required given the implicit converstion)
    public Question Get(int foo) =>
        foo; //(implicit conversion will take care of the conversion for you)
}

Преимущество этого подхода в том, что вы получаете все, что у вас было бы из enum, но ваш код теперь гораздо более гибок, поэтому, если вам нужно выполнять различные действия, основанные на значении Question, вы можете поместить логику в Question сам (то есть в предпочтительном режиме ОО), а не помещать в регистр множество операторов case для решения каждого сценария.


Примечание: ответ обновлен 2018-04-27, чтобы использовать функции C # 6; то есть выражения объявления и определения тела лямбда-выражения. См. история изменений для исходного кода. Это дает преимущество, делая определение немного менее многословным; которая была одной из основных жалоб на подход этого ответа.

17 голосов
/ 11 июня 2012

Если вы хотите получить целое число для значения enum, которое хранится в переменной, тип которого будет Question, для использования, например, в методе, вы можете просто сделать это, как я написал в этом примере:

enum Talen
{
    Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}

Talen Geselecteerd;    

public void Form1()
{
    InitializeComponent()
    Geselecteerd = Talen.Nederlands;
}

// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
    this.Text = Convert.ToInt32(e).ToString();
}

Это изменит заголовок окна на 4, потому что переменная Geselecteerd равна Talen.Nederlands. Если я изменю его на Talen.Portugees и снова вызову метод, текст изменится на 3.

Мне было трудно найти это простое решение в интернете, и я не смог его найти, поэтому я что-то тестировал и выяснил это. Надеюсь это поможет. ;)

14 голосов
/ 23 июля 2011

Чтобы убедиться, что значение перечисления существует, а затем проанализировать его, вы также можете сделать следующее.

// Fake Day of Week
string strDOWFake = "SuperDay";
// Real Day of Week
string strDOWReal = "Friday";
// Will hold which ever is the real DOW.
DayOfWeek enmDOW;

// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
// This will never be reached since "SuperDay" 
// doesn't exist in the DayOfWeek enumeration.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
    // This will parse the string into it's corresponding DOW enum object.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}

// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");

Надеюсь, это поможет.

...