Получить значение 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 06:46:39
nawfal 9.06.2013 11:54:00
Я знаю, что опаздываю на вечеринку, но вместо того, чтобы определить свой метод, как get(int foo)вы можете определить его, а get(Question foo)затем выполнить кастинг внутри метода, вы можете вызвать свой метод какQuestions.Get(Question.Role)
Joe 7.02.2017 15:10:56
27 ОТВЕТОВ
РЕШЕНИЕ

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

int something = (int) Question.Role;

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

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

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

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

long something = (long)StarsInMilkyWay.Wolf424B;
2324
27.02.2018 15:20:50
@ Гарри, это не правда. Вы можете создать Перечисление без приведения, это не обязательно. и я назначаю номер только в особых случаях, в большинстве случаев я оставляю его как значение по умолчанию. но вы можете сделать enum Test { Item = 1 }и увидеть, что 1 == (int)Test.Itemэто равно.
Jaider 28.06.2012 20:47:57
@ Jaider (int)Test.ItemЭто актерский состав! () - явный оператор приведения.
Sinthia V 26.07.2012 19:02:32
@Sinthia V он сказал, что вы можете создать его без кастинга, что правильно
Paul Ridgway 17.08.2012 18:30:11
Если базовый тип для enum Questionне был, intно longэто приведение будет усекать Roleинтегральное значение!
quaylar 29.10.2013 16:14:19
Когда вы принимаете Enumв качестве параметра, вы знаете, что вы можете получить только фиксированное количество возможных интегральных значений. С другой стороны, если вы просто берете an int, то вам нужно проверить, intнаходится ли это в пределах допустимых значений, что усложнит код. Вы всегда можете переопределить свои подписи как `` `public void MyMethod (int x) {// сделать что-то с x} public void MyMethod (Enum x) {this.MyMethod ((int) x); } `` ``
percebus 18.08.2015 16:52:31
Question question = Question.Role;
int value = (int) question;

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

87
3.06.2009 06:48:16
Вопрос о временной переменной не нужен.
Gishu 3.06.2009 06:51:01
Так что-то вроде этого Questions.Get (Convert.ToInt16 (Question.Applications))
jim 3.06.2009 06:51:13
Вы можете просто разыграть в любом направлении; Единственное, на что нужно обратить внимание, это на то, что перечисления ничего не приводят в исполнение (значение перечисления может быть 288, даже если с таким числом не существует Вопроса)
Marc Gravell♦ 3.06.2009 06:54:57
@jim: Нет, просто приведите значение: Questions.Get ((int) Question.Applications);
Guffa 3.06.2009 06:55:13
@Gishu Можно сказать, что это ... сомнительно. ;)
Felix D. 16.12.2017 16:10:50

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

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2
40
8.12.2019 16:14:40
Nitpick: это перечисление уже int. Другие перечисления могут быть разных типов - попробуйте "enum SmallEnum: byte {A, B, C}"
mqp 3.06.2009 06:56:05
Абсолютная правда. Ссылка C #: «Каждый тип перечисления имеет базовый тип, который может быть любым целым типом, кроме char».
Michael Petrotta 3.06.2009 06:59:04

Пример:

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

И в коде, чтобы получить значение enum:

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

или

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

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

33
8.12.2019 16:15:01
Это на самом деле компилируется?
Peter Mortensen 7.01.2016 20:04:00
Может ли нечто, что является Раджем, быть Рахулом или Приянкой? Ваши ценности конфликтуют и должны удваиваться, чтобы быть уникальными, например, 0, 1, 2, 4, 8 и т. Д. Это моя основная проблема с перечислениями.
Timothy Gonzalez 14.11.2016 21:58:04
@TimothyGonzalez на самом деле перечисления просто считают до 1, если вы явно не указали их значение;)
derHugo 10.10.2019 22:30:49
@derHugo, это зависит от того, что вы предполагаете, что числовые значения равны основанию 10 или основанию 2.
Timothy Gonzalez 11.10.2019 14:57:49
@TimothyGonzalez ну там не так много , чтобы предположить ... Я просто указал, что по умолчанию они просто подсчитывают 1в intкроме вас явно определить иначе
derHugo 11.10.2019 14:59:48

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

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

302
27.02.2018 15:05:52
Этот метод доказал свою ценность для меня при работе с универсальным типом, где T: enum (на самом деле T: struct, IConvertible, но это другая история).
aboy021 5.07.2011 23:20:54
Как бы вы изменили это, чтобы распечатать шестнадцатеричное значение стороны? В этом примере показано десятичное значение. Проблема в том, что varэто тип object, поэтому вам нужно распаковать его, и он станет более грязным, чем мне бы хотелось.
Mark Lakata 9.11.2012 02:15:11
Я думаю , вы должны изменить пример в вашем примере будет всегда . object val = Convert...etcvarobject
Mesh 23.10.2013 08:20:48
@TimAbell Все, что я действительно могу сказать, - это то, что мы обнаружили, что динамически скомпилированные страницы aspx (где вы должны развернуть файлы .cs на работающем сервере) назначали целые числа по-разному для каждого значения. Это означало, что сериализованные объекты на одной машине были десериализованы с разными значениями на другой машине и фактически были повреждены (что приводило к часам путаницы). Мы подняли его с помощью MS, и я, кажется, вспоминаю, что они сказали, что автоматически сгенерированные целые не гарантировались одинаковыми при сборке в разных версиях фреймворка.
NickG 24.03.2015 09:42:39
@TimAbell В отдельном случае разработчик удалил устаревшее / неиспользуемое значение Enum, в результате чего все остальные значения в последовательности вышли на единицу. Таким образом, наши стандарты кодирования теперь требуют, чтобы идентификаторы всегда указывались явно, в противном случае добавление / удаление или даже автоматическое форматирование кода (например, сортировка по алфавиту) изменит все значения, вызывающие повреждение данных. Я настоятельно рекомендую всем указывать все целые числа Enum явно. Это очень важно, если они соотносятся с внешними (база данных) сохраненными значениями.
NickG 24.03.2015 09:46:02

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

// 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() + ".");
16
8.12.2019 16:21:50

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

20
8.12.2019 16:24:57
кодирование на голландском. о, Боже.
WiseStrawberry 9.01.2019 14:57:07
К сожалению, этот подход дает плохую производительность, чем больше вы используете его. Я попробовал это в некотором моем коде, и со временем мое приложение становилось все медленнее и медленнее, с все меньшим использованием процессора. Это подразумевало, что потоки чего-то ожидали - я предполагаю какую-то сборку мусора, возможно, из-за помещения параметра enum в ToInt32 (). Переключившись на простой int.Parse (), я смог полностью устранить эту низкую производительность, и производительность осталась прежней, независимо от того, как долго выполнялся код.
Greg 4.02.2019 18:38:32

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

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

197
27.02.2018 16:43:28
Я бы использовал, static readonly intпотому что константы скомпилированы в их жесткие значения. См. Stackoverflow.com/a/755693/492
CAD bloke 15.05.2013 23:16:22
Это решение на самом деле не дает реальной выгоды от строго типизированных перечислений. Если бы я только хотел передать GameState-enum-параметр конкретному методу, например, компилятор не должен позволять мне передавать какую-либо переменную типа int в качестве параметра.
thgc 12.04.2014 18:24:41
@CADBloke, именно поэтому вы будете использовать, constа не static readonlyпотому, что каждый раз, когда вы сравниваете, static readonlyвы вызываете метод, чтобы получить значение переменной, тогда как с помощью constвы сравниваете два типа значений напрямую.
blockloop 14.08.2014 17:11:55
@ brettof86 Да, const будет быстрее, если ограничение компиляции никогда не будет проблемой, тогда все хорошо.
CAD bloke 15.08.2014 10:57:48
@ Зак Я не очень хорошо объяснил это, compilation limitationимея в виду, что значение жестко закодировано, когда вы компилируете его, поэтому любое изменение этого значения потребует перекомпиляции всех сборок, использующих его. Я склонен согласиться с вами по поводу использования, потому что изменение значений будет иметь далеко идущие последствия.
CAD bloke 22.04.2015 21:53:09

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

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();
10
8.12.2019 16:29:01
Бронек, то, что ты сделал, это создал неинформативный синтаксис с помощью (не универсального, кстати) метода расширения, который на самом деле занимает больше времени для записи. Я не вижу, как это лучше, чем оригинальное решение от Tetraneutron. Давайте не будем превращать это в чат, помощь всегда приветствуется в stackoverflow, и все здесь, чтобы помочь. Пожалуйста, примите мой комментарий как конструктивную критику.
Benjamin Gruenbaum 10.12.2012 00:28:00
Бенджамин, во-первых, почему ты удалил мой комментарий? Я не понимаю твоих решений - может быть, кто-то другой из сообщества согласится с моим комментарием. Во-вторых, мое решение обернуло одно Tetraneutron, и оно точно и легче, и меньше написано, потому что IntelliSense предлагает метод расширения. Так что я думаю, что ваше решение не является беспристрастным и репрезентативным. Я вижу много аналогичных ответов по стеку, и это нормально. В любом случае, я использую свое решение, и, возможно, некоторые люди выберут мое решение в будущем, но эти негативные моменты затрудняют поиск. Самое главное, это правильно, а не копировать.
Bronek 10.12.2012 03:20:15
@Bronek Если вы не пингуете меня, у меня нет никаких признаков того, что вы ответили. Я не удалил ваш комментарий, у меня нет возможности или хочу сделать это. Скорее всего, мод пришел и удалил его - вы можете отметить его для внимания модератора и спросить, почему или еще лучше - спросите о переполнении стека мета . У меня есть мнение о вашем решении с точки зрения программирования, которое совершенно правильно для меня - это то, для чего нужны комментарии, не нужно воспринимать это как личное.
Benjamin Gruenbaum 7.08.2013 14:45:58

Самым простым решением, которое я могу придумать, является перегрузка 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);
    }
}
3
8.12.2019 16:30:59

Недавно я перешел от использования перечислений в моем коде в пользу использования классов с защищенными конструкторами и предопределенными статическими экземплярами (благодаря Roelof - C # Enure 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себя (то есть в предпочтительном OO fashion) вместо того, чтобы помещать в ваш код множество операторов case для решения каждого сценария.


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

28
27.04.2018 08:55:31
Я предполагаю, что это компромисс между явным приведением и кодом, который вы должны написать, чтобы обойти его. Все еще люблю реализацию, просто жаль, что это не было так долго. +1
Lankymart 2.08.2013 10:40:29
Я использовал несколько различных типов классов, структурированных аналогично этому. Я нахожу, что они творят чудеса, пытаясь следовать методологии «не дай мне быть идиотом позже».
James Haug 8.09.2016 16:13:08

С другой стороны, если вы хотите получить 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);

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

79
13.08.2015 00:12:45
Второй самый быстрый, хотя.
Johan B 16.06.2019 11:47:55
Как тот, кто привык использовать Mixins в моддинге Minecraft, второй кажется очевидным победителем.
Sollace 14.10.2019 07:46:14

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

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}
2
14.01.2014 20:28:07
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, который обслуживает такого рода ожидания во многих областях.

12
27.02.2018 17:07:43

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

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

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

var intValue = Question.Role.IntValue();
8
8.12.2019 17:12:16
int number = Question.Role.GetHashCode();

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

11
27.10.2015 12:26:37
GetHashCode - это один из способов получить значение из общей маски Enum
ThanhLD 9.11.2018 04:08:07
Обратите внимание , что это только «законным» для bool*, byte, ushort, int, и uint**. GetHashCode для других типов изменяет значение, например, выполняет некоторые битовые смещения и xors. (* 1/0, ** приведено к int, конечно). Но в общем, просто не делайте этого, если это не ваш личный код.
AnorZaken 18.02.2020 13:57:49

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

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

Это приведет к:

Name: Role, Value: 2
13
8.12.2019 17:13:40

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

Это прекрасно работает для меня. Таким способом вы можете избежать приведения типов в вашем 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;
    }
}
14
8.12.2019 17:18:15
Возможно, потому что выполнение (int) customFlag меньше набирает текст и делает более или менее одно и то же?
Tim Keating 11.11.2014 17:32:34
Re "Может быть, я пропустил это, но кто-нибудь пробовал простой общий метод расширения ?" SixOThree сказал : « Вместо этого используйте метод расширения », а Бронек сказал: «Вы можете сделать это, внедрив метод расширения в определенный вами тип перечисления» .
Peter Mortensen 8.12.2019 17:27:43

Мой любимый хак с 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

Отказ от ответственности:

Это не работает для перечислений, основанных на долго.

4
8.12.2019 17:30:38

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

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

int answer = (int)Sample.Book;

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

3
8.12.2019 17:32:23

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

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

Private value As Integer = CInt(Question.Role)
2
8.12.2019 17:32:54
Вопрос к C #.
Ctrl S 19.11.2018 13:37:00
В заголовке написано «Получить значение int из enum в C #» .
Peter Mortensen 8.12.2019 17:33:28

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

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;
}
4
16.11.2018 06:25:40

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

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;
5
16.11.2018 06:49:35
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);
}
7
8.12.2019 17:35:18
масть - «10. (карточные игры). Каждый из наборов колоды карт отличается по цвету и / или определенным эмблемам, таким как пики, сердца, алмазы или трефы традиционных англо-испаноязычных и французских игральных карт».
Peter Mortensen 8.12.2019 17:36:03
Объяснение примера кода будет в порядке ( отредактировав свой ответ , а не здесь, в комментариях).
Peter Mortensen 8.12.2019 17:42:49
Ноль, как правило, зарезервирован для неустановленного / неизвестного состояния в перечислениях, необычно определять его таким образом
Chad Grant 27.12.2019 18:59:53

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

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;
    }
0
8.12.2019 17:38:18
пожалуйста, нет, вы можете сделать все это в одной строке Convert.Changetype (e, e.GetTypeCode ()) и получить объект обратно, без необходимости в динамике или методе расширения
Chad Grant 27.12.2019 19:05:09
Я не согласен с использованием Convert. Просто использовать актерский состав будет проще. Мое намерение состояло в том, чтобы иметь возможность преобразовать любое перечисление в его значение без использования приведения. Это позволяет изменять тип enum без необходимости изменения всех связанных приведений - но когда это происходит? Метод расширения работает правильно. Тем не менее, у меня есть проблема с этим в том, что, поскольку он является динамическим, компилятор не может проверить тип (очевидно, для всего оператора), что означает, что проверка типа происходит при запуске - не хорошее решение. Я думаю, что я вернусь к броскам.
Jeff 22.02.2020 20:19:23
Я не говорил использовать его вместо приведения, просто этот код бессмысленный и ничего не выполняет, на самом деле усугубляет проблему. Я бы порекомендовал удалить это решение
Chad Grant 22.02.2020 20:44:17

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

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

Это приведет value == 2.

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

5
8.12.2019 17:42:07
Это верно только в том случае, если enum помещается внутри, intконечно, так как GetHashCodeвозвращает целое число.
RB. 14.08.2019 14:59:13

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

Question question = Question.Role;
int value = Convert.ToInt32(question);
3
8.12.2019 17:41:36