Получить значение int из перечисления в C #

avatar
jim
3 июня 2009 в 06:46
1815930
29
2058

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

Источник
nawfal
9 июня 2013 в 11:54
36

Наоборот: cast-int-to-enum-in-c-sharp.

Joe
7 февраля 2017 в 15:10
12

Я знаю, что опаздываю на вечеринку, но вместо определения вашего метода как get(int foo) вы можете определить его как get(Question foo), а затем выполнить приведение внутри метода, вы можете вызвать свой метод как Questions.Get(Question.Role)

گلی
18 июля 2021 в 07:35
0

попробуйте это: int int_Choose = (int) Question.Role;

Ответы (29)

avatar
Tetraneutron
3 июня 2009 в 06:49
2632

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

int something = (int) Question.Role;

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

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

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

вам следует использовать

long something = (long)StarsInMilkyWay.Wolf424B;
Jaider
28 июня 2012 в 20:47
24

@ Гарри, это неправда. Вы можете создать Enumeration без приведения, это не обязательно. и я назначаю номер только в особых случаях, в большинстве случаев я оставляю его по умолчанию. но вы можете сделать enum Test { Item = 1 } и увидеть, что 1 == (int)Test.Item равно.

Sinthia V
26 июля 2012 в 19:02
41

@Jaider (int)Test.Item Это актерский состав! () - это явный оператор приведения.

Paul Ridgway
17 августа 2012 в 18:30
51

@Sinthia V он сказал, что вы можете создать без кастинга, что правильно

quaylar
29 октября 2013 в 16:14
8

Если базовый тип для enum Question был не int, а long, это приведение приведет к усечению целого значения Role!

El Mac
8 апреля 2015 в 09:19
0

@PaulRidgway, вопрос не в этом.

percebus
18 августа 2015 в 16:52
2

Когда вы принимаете Enum в качестве параметра, вы знаете, что можете получить только фиксированное количество возможных целых значений. С другой стороны, если вы просто возьмете int, тогда вам нужно будет проверить, находится ли этот int в пределах допустимых значений., Что усложняет код. Вы всегда можете переопределить свои подписи, например: `` public void MyMethod (int x) {// сделать что-нибудь с x} public void MyMethod (Enum x) {this.MyMethod ((int) x); } `` ``

Neil Busse
9 февраля 2018 в 17:52
1

Я бы не стал использовать Long и Enum, но может быть конкретный вариант использования, в котором это действительно имеет смысл.

Felix Keil
11 марта 2020 в 06:22
1

@NeilBusse Возможно, помеченные перечисления

Sarasjd
13 марта 2021 в 08:24
0

это было лучше всего для меня

avatar
Tayron Ovares
10 июня 2021 в 16:09
0
public enum ViewType
{
    List = 1,
    Table = 2,
};
            
// You can use the Enum type as a parameter, so any enumeration from any enumerator 
// cshtml
// using proyects.Helpers
// @if (Model.ViewType== (int)<variable>.List )
avatar
IggyBar
12 января 2021 в 02:14
0

предоставит вам список со всеми целыми значениями перечисления:

Список enumValues ​​= Enum.GetValues ​​(typeof (EnumClass)). Cast (). ToList ();

avatar
Abrar Jahin
23 сентября 2020 в 06:54
1

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

Если ваш enum такой:

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

И вам нужно преобразовать в int, затем сделайте следующее -

Question q = Question.Role;
.............
.............
int something = (int) q;

Re-

В C # существует два типа приведения типов:

  • Неявное приведение ( автоматически ) - преобразование меньшего типа в больший размер, например -

char -> int -> long -> float -> double

  • Явное приведение ( вручную ) - преобразование большего типа в тип меньшего размера, например -

double -> float -> long -> int -> char

Больше можно найти в здесь .

avatar
GinCanhViet
12 августа 2019 в 03:27
9

Использование:

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

Результатом будет value == 2.

Это верно, только если перечисление помещается внутри int.

RB.
14 августа 2019 в 14:59
2

Это верно только в том случае, если перечисление помещается в int, конечно, поскольку GetHashCode возвращает целое число.

avatar
Jeff
2 марта 2019 в 17:55
-2

Я придумал этот метод расширения, который включает текущие языковые функции. Используя динамический, мне не нужно делать этот универсальный метод и указывать тип, который упрощает и согласовывает вызов:

public static class EnumEx
{
    public static dynamic Value(this Enum e)
    {
        switch (e.GetTypeCode())
        {
            case TypeCode.Byte:
            {
                return (byte) (IConvertible) e;
            }

            case TypeCode.Int16:
            {
                return (short) (IConvertible) e;
            }

            case TypeCode.Int32:
            {
                return (int) (IConvertible) e;
            }

            case TypeCode.Int64:
            {
                return (long) (IConvertible) e;
            }

            case TypeCode.UInt16:
            {
                return (ushort) (IConvertible) e;
            }

            case TypeCode.UInt32:
            {
                return (uint) (IConvertible) e;
            }

            case TypeCode.UInt64:
            {
                return (ulong) (IConvertible) e;
            }

            case TypeCode.SByte:
            {
                return (sbyte) (IConvertible) e;
            }
        }

        return 0;
    }
Chad Grant
27 декабря 2019 в 19:05
0

пожалуйста, нет, вы можете сделать все это в одной строке Convert.Changetype (e, e.GetTypeCode ()) и получить объект обратно, нет необходимости в динамике или методе расширения

Jeff
22 февраля 2020 в 20:19
0

Я не согласен с использованием Convert. Было бы проще использовать гипс. Мое намерение состояло в том, чтобы иметь возможность преобразовать любое перечисление в его значение без использования приведения. Это позволяет изменять тип перечисления без изменения всех связанных приведений - но когда это произойдет? Метод расширения работает правильно. Однако у меня проблема в том, что, поскольку он динамический, компилятор не может проверить тип (очевидно, для всего оператора), что означает, что проверка типа выполняется при запуске - не лучшее решение. Думаю, вернусь к слепкам.

Chad Grant
22 февраля 2020 в 20:44
2

Я не сказал использовать его поверх приведения, просто этот код бессмысленен и ничего не делает, на самом деле только усугубляет проблему. Я бы рекомендовал удалить это решение

avatar
Gauravsa
27 июля 2018 в 06:29
8
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 a 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);
}
Peter Mortensen
8 декабря 2019 в 17:42
0

Объяснение примера кода будет в порядке (отредактировав свой ответ, а не здесь, в комментариях).

Chad Grant
27 декабря 2019 в 18:59
0

ноль обычно зарезервирован для состояния unset / unkown в перечислениях, что необычно для его определения таким образом

avatar
Jeffrey Ferreiras
6 декабря 2017 в 05:14
6

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

enum Box
{
    HEIGHT,
    WIDTH,
    DEPTH
}

public static void UseEnum()
{
    int height = Box.HEIGHT.GetEnumValue<int>();
    int width = Box.WIDTH.GetEnumValue<int>();
    int depth = Box.DEPTH.GetEnumValue<int>();
}

public static T GetEnumValue<T>(this object e) => (T)e;
avatar
Kamran Shahid
16 декабря 2016 в 06:58
4

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

public static string ToEnumString<TEnum>(this int enumValue)
{
    var enumString = enumValue.ToString();
    if (Enum.IsDefined(typeof(TEnum), enumValue))
    {
        enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
    }
    return enumString;
}
avatar
VPP
12 апреля 2016 в 07:09
0

В Visual Basic это должно быть:

Public Enum Question
    Role = 2
    ProjectFunding = 3
    TotalEmployee = 4
    NumberOfServers = 5
    TopBusinessConcern = 6
End Enum

Private value As Integer = CInt(Question.Role)
Ctrl S
19 ноября 2018 в 13:37
4

Вопрос для C #.

Peter Mortensen
8 декабря 2019 в 17:33
3

В заголовке говорится: «Получить значение int из перечисления в C #» .

avatar
Vivek
3 августа 2015 в 07:12
3

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

public enum Sample
{
    Book = 1, 
    Pen = 2, 
    Pencil = 3
}

int answer = (int)Sample.Book;

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

avatar
Erik Karlsson
26 июня 2015 в 16:51
4

Мой любимый хак с перечислениями 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

Заявление об отказе от ответственности :

Не работает для перечислений на основе long.

avatar
Doug
27 сентября 2014 в 01:30
14

Может быть, я это пропустил, но пробовал ли кто-нибудь простой универсальный метод расширения?

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

    public static void Main()
    {
        int test = MyCSharpWrapperMethod(TestEnum.Test1);

        Debug.Assert(test == 1);
    }

    public static int MyCSharpWrapperMethod(TestEnum customFlag)
    {
        return MyCPlusPlusMethod(customFlag.GetValue<int>());
    }

    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<T>(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;
    }
}
Tim Keating
11 ноября 2014 в 17:32
0

Возможно, потому, что выполнение (int) customFlag меньше печатает и делает более или менее то же самое?

Peter Mortensen
8 декабря 2019 в 17:27
0

Re «Возможно, я пропустил это, но пробовал ли кто-нибудь простой универсальный метод расширения : SixOThree сказал «Используйте метод расширения» вместо « и Бронек сказал « Вы можете сделать это, реализовав метод расширения для определенного типа enum »<82877>.

avatar
plavozont
19 сентября 2014 в 05:42
17

Еще один способ:

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

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

Name: Role, Value: 2
Andy
28 октября 2020 в 17:35
1

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

avatar
JaimeArmenta
18 сентября 2014 в 22:53
12
int number = Question.Role.GetHashCode();

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

ThanhLD
9 ноября 2018 в 04:08
0

GetHashCode - один из способов получить значение из общей маски Enum

AnorZaken
18 февраля 2020 в 13:57
0

Обратите внимание, что это "допустимо" только для bool *, byte, ushort, int и uint **. GetHashCode для других типов изменяет значение, например делает несколько битовых сдвигов и xors. (* 1/0, **, конечно, преобразовано в int). Но в целом просто не делайте этого, если только это не ваш собственный частный код.

avatar
SixOThree
21 апреля 2014 в 02:51
11

Используйте вместо этого метод расширения:

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

И использование немного красивее:

var intValue = Question.Role.IntValue();
avatar
WonderWorker
31 марта 2014 в 16:35
13
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, который удовлетворяет такие ожидания во многих областях.

avatar
Nalan Madheswaran
14 января 2014 в 20:28
3

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

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}
avatar
nawfal
1 декабря 2013 в 08:47
96

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

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

Johan B
16 июня 2019 в 11:47
3

Но второй - самый быстрый.

Sollace
14 октября 2019 в 07:46
1

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

andreyk2 Hohlov
17 августа 2020 в 09:06
0

И 5-й вариант (как говорится в большинстве ответов): int i = (int) e; (без предварительного приведения к объекту)

nawfal
18 августа 2020 в 09:48
0

@ andreyk2Hohlov Cannot convert type 'System.Enum' to 'int'

avatar
JohnLBevan
30 марта 2013 в 01:08
31

Недавно я отказался от использования перечислений в своем коде в пользу вместо использования классов с защищенными конструкторами и предопределенными статическими экземплярами (благодаря Roelof - C # Ensure 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<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)
}

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


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

user692942
2 августа 2013 в 10:40
2

Я предполагаю, что это компромисс между явным приведением и кодом, который вы должны написать, чтобы его обойти. Все еще люблю реализацию, просто хочу, чтобы она не была такой длинной. +1

James Haug
8 сентября 2016 в 16:13
3

Я использовал несколько разных типов классов, структурированных аналогично этой. Я считаю, что они творят чудеса, пытаясь следовать методике «не позволяй мне быть идиотом позже».

avatar
Grx70
28 января 2013 в 13:52
4

Самым простым решением, которое я могу придумать, является перегрузка метода 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);
    }
}
avatar
Bronek
9 декабря 2012 в 22:09
11

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

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();
Benjamin Gruenbaum
10 декабря 2012 в 00:28
7

Бронек, вы создали неинформативный синтаксис с помощью метода расширения (не общего, кстати), который на самом деле требует больше времени для написания. Я не вижу, чем оно лучше оригинального решения Tetraneutron. Давайте не будем превращать это в чат, помощь всегда приветствуется в coderhelper, и все здесь готовы помочь. Прошу воспринимать мой комментарий как конструктивную критику.

Bronek
10 декабря 2012 в 03:20
3

Бенджамин, во-первых, почему вы удалили мой комментарий? Я не понимаю ваших решений - может быть, кто-то еще в сообществе согласится с моим комментарием. Во-вторых, мое решение обертывает комментарий Tetraneutron, и, точнее, его легче и меньше писать, потому что IntelliSense предлагает метод расширения, поэтому я думаю, что ваше решение не является беспристрастным и репрезентативным. Я вижу много похожих ответов на Stack, и это нормально. В любом случае я использую свое решение, и, возможно, некоторые люди выберут мое решение в будущем, но эти отрицательные моменты затрудняют поиск. Прежде всего, это правильно, а не копирует.

Benjamin Gruenbaum
7 августа 2013 в 14:45
4

@Bronek Если ты не пингуешь меня, я не пойму, что ты ответил. Я не удалил ваш комментарий У меня нет возможности или желания сделать это. Вероятно, пришел мод и удалил его - вы можете пометить его для внимания модератора и спросить, почему, или еще лучше - спросите на Meta Stack Overflow. У меня есть мнение о вашем решении с точки зрения программирования, и я совершенно прав - это то, что для начала нужны комментарии, не нужно принимать его на свой счет.

avatar
PablosBicicleta
15 июня 2012 в 19:28
210

Объявить его как статический класс с общедоступными константами:

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

CAD bloke
15 мая 2013 в 23:16
34

Я бы использовал static readonly int, потому что константы компилируются в их жесткие значения. См. Coderhelper.com/a/755693/492

thgc
12 апреля 2014 в 18:24
104

Это решение фактически не дает реальных преимуществ строго типизированных перечислений. Если бы я хотел передать только GameState-enum-параметр определенному методу, например, компилятор не должен позволять мне передавать любую int-переменную в качестве параметра.

blockloop
14 августа 2014 в 17:11
13

@CADBloke, именно поэтому вы должны использовать const, а не static readonly, потому что каждый раз, когда вы сравниваете static readonly, вы вызываете метод, чтобы получить значение переменной, тогда как с const вы сравниваете два типы значений напрямую.

CAD bloke
15 августа 2014 в 10:57
3

@ brettof86 Да, константа была бы быстрее, если ограничение компиляции никогда не будет проблемой, тогда все хорошо.

Zack
22 апреля 2015 в 14:05
0

@CADbloke Что вы имеете в виду под "ограничением компиляции"? Вы используете static readonly int, потому что вы загружаете значения динамически из файла настроек или чего-то еще? Я думаю, что если вы используете этот статический класс вместо перечисления, он должен быть const, потому что значения не изменятся.

CAD bloke
22 апреля 2015 в 21:53
2

@Zack Я не очень хорошо объяснил это, по compilation limitation я имею в виду, что значение жестко запрограммировано, когда вы его компилируете, поэтому любое изменение этого значения потребует, чтобы все сборки, использующие его, должны быть перекомпилирован. Я склонен согласиться с вами в отношении использования, потому что изменение значений будет иметь далеко идущие последствия.

David Mårtensson
16 марта 2016 в 13:53
0

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

Timothy Gonzalez
14 ноября 2016 в 20:59
0

Я искал альтернативу, но, похоже, это лучший вариант со всей сложностью, как указано в основных ответах, связанных с преобразованием перечисления в int.

quemeful
9 февраля 2017 в 16:29
0

На мой взгляд, это лучший ответ с точки зрения скорости разработки и удобочитаемости. Ограничение компиляции, если оно есть, того стоит.

MIKE
1 февраля 2018 в 02:21
1

умный! приведение каждого перечисления так некрасиво на вид

Chad Grant
27 декабря 2019 в 19:03
0

Это не имеет ничего общего с перечислениями / перечислениями

Chris Catignani
25 марта 2021 в 17:50
0

Мне нравятся константы для использования Case.

avatar
Mathijs Van Der Slagt
10 июня 2012 в 22:58
21

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

Greg
4 февраля 2019 в 18:38
0

К сожалению, чем больше вы используете этот подход, тем хуже его производительность. Я пробовал это в каком-то своем коде, и со временем мое приложение становилось все медленнее и медленнее, с все меньшей и меньшей загрузкой ЦП. Это означало, что потоки чего-то ждали - я предполагаю, что это какая-то сборка мусора, возможно, из-за упаковки параметра enum в ToInt32 (). Перейдя на простой int.Parse (), я смог полностью устранить эту низкую производительность, и производительность оставалась неизменной независимо от того, как долго выполнялся код.

avatar
Nathon
22 июля 2011 в 20:56
17

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

// 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() + ".");
avatar
cecilphillip
9 июля 2010 в 14:54
336

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

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

aboy021
5 июля 2011 в 23:20
43

Эта методика показала мне свою ценность при работе с универсальным типом, где T: enum (на самом деле T: struct, IConvertible, но это другая история).

Mark Lakata
9 ноября 2012 в 02:15
2

Как бы вы изменили это, чтобы распечатать шестнадцатеричное значение стороны? В этом примере показано десятичное значение. Проблема в том, что var относится к типу object, поэтому вам нужно распаковать его, и он становится более беспорядочным, чем хотелось бы.

theLaw
9 июня 2014 в 16:05
1

Если вы хотите преобразовать в int, попробуйте (в случае перечисления Sides: int) [...] объект val = Convert.ChangeType (side, typeof (int)); [...]

NickG
6 августа 2014 в 09:58
1

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

Tim Abell
23 марта 2015 в 20:24
0

@NickG, могу я спросить, что привело к изменению присвоенных номеров? Я спрашиваю, потому что никогда не слышал об этом и всегда полагался на задокументированное поведение - msdn.microsoft.com/en-us/library/sbbt4032.aspx «По умолчанию первый перечислитель имеет значение 0 "

NickG
24 марта 2015 в 09:42
3

@TimAbell Все, что я действительно могу сказать, это то, что мы обнаружили, что динамически скомпилированные страницы aspx (где вам нужно развернуть файлы .cs на активный сервер) присваивали целые числа по-разному каждому значению. Это означало, что сериализованные объекты на одной машине десериализовались с разными значениями на другой машине и фактически повреждались (вызывая часов путаницы). Мы подняли его с помощью MS, и я, кажется, припоминаю, что они сказали, что автоматически сгенерированные целые числа не гарантированно будут одинаковыми при построении в разных версиях фреймворка.

NickG
24 марта 2015 в 09:46
6

@TimAbell В отдельном случае разработчик удалил устаревшее / неиспользуемое значение Enum, в результате чего все остальные значения в последовательности были потеряны на единицу. Таким образом, наши стандарты кодирования теперь требуют, чтобы идентификаторы всегда указывались явно, в противном случае добавление / удаление или даже автоматическое форматирование кода (например, сортировка по алфавиту) изменит все значения, вызывая повреждение данных. Я настоятельно рекомендую всем явно указывать все целые числа Enum. Это очень важно, если они соотносятся с хранимыми извне (в базе данных) значениями.

Tim Abell
24 марта 2015 в 13:30
0

Спасибо за информацию @NickG, это действительно ценный контекст. Итак, если я могу резюмировать: как только что-либо, внешнее по отношению к вашей программе, узнает о целочисленных значениях, любые изменения в них становятся реальной проблемой, а наличие явной нумерации делает последующие поломки менее вероятными.

NickG
24 марта 2015 в 13:32
0

Абсолютно. Или, если вы подозреваете, что по какой-либо причине вам, возможно, придется изменить значения перечисления (включая удаление или даже изменение порядка кода). Я бы просто всегда делал это, потому что нет причин не делать этого.

Tim Abell
24 марта 2015 в 13:57
1

Я бы сказал, что «всегда» - это излишне (единственное абсолютное правило - не бывает абсолютов). Если ваше перечисление никогда не выходит за пределы вашей программы, вы добавляете незначительные накладные расходы на редактирование списка перечислений, заставляя людей выяснять, что компилятор сделал бы для вас. То, заботитесь ли вы о модификациях, зависит от того, где они используются. ИМХО.

Jeppe Stig Nielsen
14 октября 2015 в 19:06
1

Получение упакованного (object) целочисленного типа не очень полезно, если вы не знаете ширину целочисленного типа во время компиляции! Если вы хотите просто записать числовое значение, используйте Sides side = Sides.Bottom; Console.WriteLine("{0:D}", side);. Если вам нужна ссылка на строку, это string sideStr = side.ToString("D");. И чтобы ответить на комментарий @MarkLakata, просто используйте X вместо D, то есть Console.WriteLine("{0:X}", side) или side.ToString("X"). Строчные x дают шестнадцатеричные числа со строчными цифрами от a до f.

avatar
sooraj
25 сентября 2009 в 10:43
36

Пример:

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.

Timothy Gonzalez
14 ноября 2016 в 21:58
0

Может ли что-то, что является Раджем, быть также Рахулом или Приянкой? Ваши ценности конфликтуют и должны удвоиться, чтобы быть уникальными, например. 0, 1, 2, 4, 8 и т. Д. Это моя основная забота о перечислениях.

derHugo
10 октября 2019 в 22:30
0

@TimothyGonzalez на самом деле перечисляет просто подсчитывает до 1, если вы явно не указываете их значение;)

Timothy Gonzalez
11 октября 2019 в 14:57
0

@derHugo, который зависит от того, принимаете ли вы числовые значения с основанием 10 или основанием 2.

derHugo
11 октября 2019 в 14:59
1

@TimothyGonzalez: ну, нечего предполагать ... Я просто указал, что по умолчанию они просто подсчитывают 1 в int, если вы явно не определяете иное

avatar
Michael Petrotta
3 июня 2009 в 06:51
42

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

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2
mqp
3 июня 2009 в 06:56
15

Nitpick: это перечисление уже является int. Другие перечисления могут быть разных типов - попробуйте "enum SmallEnum: byte {A, B, C}"

Michael Petrotta
3 июня 2009 в 06:59
9

Абсолютная правда. Справка по C #: «Каждый тип перечисления имеет базовый тип, который может быть любым целым типом, кроме char».

avatar
jerryjvl
3 июня 2009 в 06:48
89
Question question = Question.Role;
int value = (int) question;

Результатом будет value == 2.

jim
3 июня 2009 в 06:51
2

Примерно так: Questions.Get (Convert.ToInt16 (Question.Applications))

Marc Gravell♦
3 июня 2009 в 06:54
8

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

Guffa
3 июня 2009 в 06:55
1

@jim: Нет, просто введите значение: Questions.Get ((int) Question.Applications);