Получить значение int из enum в C #

У меня есть класс с именем 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)?

вопрос задан 3.06.2009
jim
8873 репутация

25 ответов


  • 1843 рейтинг

    Просто приведи enum, e. г.

    int something = (int) Question.Role;
    

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

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

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

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

    long something = (long)StarsInMilkyWay.Wolf424B;
    
    ответ дан Tetraneutron, с репутацией 21459, 3.06.2009
  • 240 рейтинг

    Поскольку перечисления могут быть любого целого типа (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);
    

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

    ответ дан cecilphillip, с репутацией 8400, 9.07.2010
  • 161 рейтинг

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

    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 или как вы его определяете.

    ответ дан PablosBicicleta, с репутацией 1701, 15.06.2012
  • 72 рейтинг
    Question question = Question.Role;
    int value = (int) question;
    

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

    ответ дан jerryjvl, с репутацией 14565, 3.06.2009
  • 55 рейтинг

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

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

    ответ дан nawfal, с репутацией 40852, 1.12.2013
  • 30 рейтинг

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

    int y = (int)Question.Role;
    Console.WriteLine(y); // prints 2
    
    ответ дан Michael Petrotta, с репутацией 50538, 3.06.2009
  • 22 рейтинг

    Пример:

    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.

    ответ дан does_not_exist, с репутацией , 25.09.2009
  • 19 рейтинг

    Недавно я перешел от использования перечислений в моем коде в пользу вместо использования классов с защищенными конструкторами и предопределенными статическими экземплярами (благодаря Roelof - C # Enval Valid Enum Values ​​- Futureproof Method ).

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

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

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


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

    ответ дан JohnLBevan, с репутацией 13195, 30.03.2013
  • 12 рейтинг

    Если вы хотите получить целое число для значения перечисления, которое хранится в переменной, тип которого будет 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.

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

    ответ дан Mathijs Van Der Slagt, с репутацией 131, 10.06.2012
  • 12 рейтинг

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

    // 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() + ".");
    

    Я надеюсь, что это помогает.

    ответ дан Nathon, с репутацией 123, 22.07.2011
  • 11 рейтинг

    Еще один способ сделать это:

    Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);
    

    Результатом будет:

    Name: Role, Value: 2
    
    ответ дан plavozont, с репутацией 406, 19.09.2014
  • 10 рейтинг

    Возможно я пропустил это, но кто-нибудь пробовал простой универсальный метод расширения. Это прекрасно работает для меня. Таким способом вы можете избежать приведения типов в вашем API, но в конечном итоге это приведет к операции изменения типа. Это хороший случай для программирования Roselyn, чтобы компилятор сделал метод GetValue для вас.

        public static void Main()
        {
            int test = MyCSharpWrapperMethod(TestEnum.Test1);
    
            Debug.Assert(test == 1);
        }
    
        public static int MyCSharpWrapperMethod(TestEnum customFlag)
        {
            return MyCPlusPlusMethod(customFlag.GetValue());
        }
    
        public static int MyCPlusPlusMethod(int customFlag)
        {
            //Pretend you made a PInvoke or COM+ call to C++ method that require an integer
            return customFlag;
        }
    
        public enum TestEnum
        {
            Test1 = 1,
            Test2 = 2,
            Test3 = 3
        }
    }
    
    public static class EnumExtensions
    {
        public static T GetValue(this Enum enumeration)
        {
            T result = default(T);
    
            try
            {
                result = (T)Convert.ChangeType(enumeration, typeof(T));
            }
            catch (Exception ex)
            {
                Debug.Assert(false);
                Debug.WriteLine(ex);
            }
    
            return result;
        }
    }    
    
    ответ дан Doug, с репутацией 142, 27.09.2014
  • 8 рейтинг
    public enum QuestionType
    {
        Role = 2,
        ProjectFunding = 3,
        TotalEmployee = 4,
        NumberOfServers = 5,
        TopBusinessConcern = 6
    }
    

    . , , это хорошая декларация.

    Вы должны привести результат к int следующим образом:

    int Question = (int)QuestionType.Role
    

    В противном случае тип по-прежнему QuestionType.

    Этот уровень строгости является способом C #.

    Одна альтернатива - вместо этого использовать объявление класса:

    public class QuestionType
    {
        public static int Role = 2,
        public static int ProjectFunding = 3,
        public static int TotalEmployee = 4,
        public static int NumberOfServers = 5,
        public static int TopBusinessConcern = 6
    }
    

    Объявлять менее элегантно, но вам не нужно приводить его в коде:

    int Question = QuestionType.Role
    

    Кроме того, вы можете чувствовать себя более комфортно с Visual Basic, который обслуживает такой тип ожидания во многих областях.

    ответ дан Knickerless-Noggins, с репутацией 4702, 31.03.2014
  • 8 рейтинг

    Вы можете сделать это, применив метод расширения к определенному вами типу перечисления:

    public static class MyExtensions
    {
        public static int getNumberValue(this Question questionThis)
        {
            return (int)questionThis;
        }
    }
    

    Это упрощает получение значения int текущего значения перечисления:

    Question question = Question.Role;
    int value = question.getNumberValue();
    

    или

    int value = Question.Role.getNumberValue();
    
    ответ дан Bronek, с репутацией 5942, 9.12.2012
  • 6 рейтинг

    Как насчет метода расширения вместо:

    public static class ExtensionMethods
    {
        public static int IntValue(this Enum argEnum)
        {
            return Convert.ToInt32(argEnum);
        }
    }
    

    А использование чуть красивее:

    var intValue = Question.Role.IntValue();
    
    ответ дан SixOThree, с репутацией 428, 21.04.2014
  • 5 рейтинг
    int number = Question.Role.GetHashCode();
    

    number должен иметь значение 2.

    ответ дан JaimeArmenta, с репутацией 59, 18.09.2014
  • 2 рейтинг

    Ниже приведен метод расширения

    public static string ToEnumString(this int enumValue)
            {
                var enumString = enumValue.ToString();
                if (Enum.IsDefined(typeof(TEnum), enumValue))
                {
                    enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
                }
                return enumString;
            }
    
    ответ дан Kamran Shahid, с репутацией 1468, 16.12.2016
  • 2 рейтинг

    Самое простое решение, о котором я могу подумать, это перегрузить метод Get(int) следующим образом:

    [modifiers] Questions Get(Question q)
    {
        return Get((int)q);
    }
    

    , где [modifiers] обычно может быть таким же, как для метода Get(int). Если Вы не можете редактировать класс Questions или по какой-либо причине не хотите этого, Вы можете перегрузить метод, написав расширение:

    public static class Extensions
    {
        public static Questions Get(this Questions qs, Question q)
        {
            return qs.Get((int)q);
        }
    }
    
    ответ дан Grx70, с репутацией 6998, 28.01.2013
  • 1 рейтинг

    Попробуйте это вместо преобразования enum в int:

    public static class ReturnType
    {
        public static readonly int Success = 1;
        public static readonly int Duplicate = 2;
        public static readonly int Error = -1;        
    }
    
    ответ дан Nalan Madheswaran, с репутацией 4572, 14.01.2014
  • 1 рейтинг

    Пример, который я хотел бы предложить, чтобы получить значение 'int' из enum: '

    public enum Sample
    {Book =1, Pen=2, Pencil =3}
    
    int answer = (int)Sample.Book;
    

    теперь ответ будет 1.

    Я надеюсь, что это может кому-то помочь.

    ответ дан Vivek, с репутацией 52, 3.08.2015
  • 1 рейтинг

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

            enum Box
            {
                HEIGHT,
                WIDTH,
                DEPTH
            }
    
            public static void UseEnum()
            {
                int height = Box.HEIGHT.GetEnumValue();
                int width = Box.WIDTH.GetEnumValue();
                int depth = Box.DEPTH.GetEnumValue();
            }
    
            public static T GetEnumValue(this object e) => (T)e;
    
    ответ дан Jeffrey Ferreiras, с репутацией 135, 6.12.2017
  • 1 рейтинг

    Мой любимый хак с int или меньшими перечислениями:

    GetHashCode();
    

    для перечисления

    public enum Test
    {
        Min = Int32.MinValue,
        One = 1,
        Max = Int32.MaxValue,
    }
    

    это

    var values = Enum.GetValues(typeof(Test));
    
    foreach (var val in values) 
    {
        Console.WriteLine(val.GetHashCode());
        Console.WriteLine(((int)val));
        Console.WriteLine(val);
    }
    

    выводит

    one
    1
    1  
    max
    2147483647
    2147483647    
    min
    -2147483648
    -2147483648    
    

    Отказ от ответственности: Не работает для перечислений на основе длинных

    ответ дан Erik Karlsson, с репутацией 134, 26.06.2015
  • 1 рейтинг

    В Vb. Должно быть

    Public Enum Question
        Role = 2
        ProjectFunding = 3
        TotalEmployee = 4
        NumberOfServers = 5
        TopBusinessConcern = 6
    End Enum
    
    Private value As Integer = CInt(Question.Role)
    
    ответ дан VPP, с репутацией 201, 12.04.2016
  • 0 рейтинг
    public enum Suit : int
    {
        Spades = 0,
        Hearts = 1,
        Clubs = 2,
        Diamonds = 3
    }
    
    Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit), "Clubs"));
    
    //from int
    Console.WriteLine((Suit)1);
    
    //From number you can also
    Console.WriteLine((Suit)Enum.ToObject(typeof(Suit), 1));
    
    if (typeof(Suit).IsEnumDefined("Spades"))
    {
        var res = (int)(Suit)Enum.Parse(typeof(Suit), "Spades");
        Console.Out.WriteLine("{0}", res);
    }
    
    ответ дан Gauravsa, с репутацией 741, 27.07.2018
  • -13 рейтинг

    Попробуйте это:

    int value = YourEnum.ToString("D");
    
    ответ дан Caryn, с репутацией 13, 10.01.2013