Найдите строку в Enum и верните Enum

163

У меня есть перечисление:

public enum MyColours
{
    Red,
    Green,
    Blue,
    Yellow,
    Fuchsia,
    Aqua,
    Orange
}

и у меня есть строка:

string colour = "Red";

Я хочу иметь возможность вернуться:

MyColours.Red

из:

public MyColours GetColour(string colour)

Пока у меня есть:

public MyColours GetColours(string colour)
{
    string[] colours = Enum.GetNames(typeof(MyColours));
    int[]    values  = Enum.GetValues(typeof(MyColours));
    int i;
    for(int i = 0; i < colours.Length; i++)
    {
        if(colour.Equals(colours[i], StringComparison.Ordinal)
            break;
    }
    int value = values[i];
    // I know all the information about the matched enumeration
    // but how do i convert this information into returning a
    // MyColour enumeration?
}

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

MyColour(2) 

приведет к

MyColour.Green
Мэтт Кларксон
источник
4
@nawfal, не нашел этого, когда я спросил об этом много лет назад. Проголосовали закрыть как дубликат.
Мэтт Кларксон

Ответы:

381

проверить System.Enum.Parse:


enum Colors {Red, Green, Blue}

// your code:
Colors color = (Colors)System.Enum.Parse(typeof(Colors), "Green");

JMarsch
источник
72
Не забывайте, что вы можете игнорировать чувствительность к регистру, передавая третий необязательный параметр «true»
Aerophilic
Именно то, что я искал! Ура!
Zame
11
@ user1531040 На самом деле, есть Enum.TryParse.
DarLom
Обратите внимание, что анализ enum всегда «завершается успешно», если ввод является числовым; он просто возвращает проанализированный номер, который затем приводится к типу перечисления. Поэтому, если вы хотите проверить, является ли какой-либо пользовательский ввод допустимым перечислением или чем-то еще, вам следует сначала проверить числовой контент. Так как он возвращает допустимое перечисление, но со значением, которое может вообще не существовать в определенных именах перечисления, вы можете столкнуться с некоторыми действительно странными проблемами.
Nyerguds
19

Вы можете привести int к перечислению

(MyColour)2

Также есть опция Enum.Parse

(MyColour)Enum.Parse(typeof(MyColour), "Red")
Guvante
источник
11

Учитывая последние и самые большие изменения в .NET (+ Core) и C # 7, вот лучшее решение:

var ignoreCase = true;
Enum.TryParse("red", ignoreCase , out MyColours colour);

переменная цвета может использоваться в рамках Enum.TryParse

Римский
источник
2

Я пометил ответ OregonGhost +1, затем попытался использовать итерацию и понял, что это не совсем правильно, потому что Enum.GetNames возвращает строки. Вы хотите Enum.GetValues:

public MyColours GetColours(string colour)
{  
   foreach (MyColours mc in Enum.GetValues(typeof(MyColours))) 
   if (mc.ToString() == surveySystem) 
      return mc;

   return MyColors.Default;
}
Colin
источник
1

Вы можете использовать, Enum.Parseчтобы получить значение enum из имени. Вы можете перебирать все значения с помощью Enum.GetNames, и вы можете просто привести int к enum, чтобы получить значение enum из значения int.

Вот так, например:

public MyColours GetColours(string colour)
{
    foreach (MyColours mc in Enum.GetNames(typeof(MyColours))) {
        if (mc.ToString().Contains(colour)) {
            return mc;
        }
    }
    return MyColours.Red; // Default value
}

или:

public MyColours GetColours(string colour)
{
    return (MyColours)Enum.Parse(typeof(MyColours), colour, true); // true = ignoreCase
}

Последний выдает ArgumentException, если значение не найдено, вы можете перехватить его внутри функции и вернуть значение по умолчанию.

OregonGhost
источник
ПРИМЕЧАНИЕ. Конечно, это должен был быть Enum.GetValues, как показано в ответе Колина.
OregonGhost
1
var color =  Enum.Parse<Colors>("Green");
pampi
источник
Это даже не компилируется. Универсального Parseметода не существует.
Жоао Менигин
Это скомпилировано и работает для меня. Может быть, это зависит от версии, которую вы используете? Я использую .NET core 3.1
Винни
0

Как упоминалось в предыдущих ответах, вы можете приводить непосредственно к базовому типу данных (int -> enum type) или анализировать (string -> enum type).

но будьте осторожны - для перечислений нет .TryParse, так что вам понадобится блок try / catch для разбора, чтобы перехватывать ошибки.

Addys
источник
3
Не было до того, как был задан этот вопрос, но теперь есть и .NET 4! msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx . Это было бы что-то вроде Enum.TryParse <MyColour> («Красный», без цвета)
WienerDog
0
class EnumStringToInt // to search for a string in enum
{
    enum Numbers{one,two,hree};
    static void Main()
    {
        Numbers num = Numbers.one; // converting enum to string
        string str = num.ToString();
        //Console.WriteLine(str);
        string str1 = "four";
        string[] getnames = (string[])Enum.GetNames(typeof(Numbers));
        int[] getnum = (int[])Enum.GetValues(typeof(Numbers));
        try
        {
            for (int i = 0; i <= getnum.Length; i++)
            {
                if (str1.Equals(getnames[i]))
                {
                    Numbers num1 = (Numbers)Enum.Parse(typeof(Numbers), str1);
                    Console.WriteLine("string found:{0}", num1);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Value not found!", ex);
        }
    }
}
Раджа
источник
2
C # имеет встроенную функциональность для этого.
Артемикс
как это ответ на вопрос? посмотрите на другие ответы для более простого кода
Firo
0

Одна вещь, которая может быть вам полезна (помимо уже действительных / хороших ответов, предоставленных до сих пор), это идея StringEnum, представленная здесь

При этом вы можете определить свои перечисления как классы (примеры в vb.net):

<StringEnumRegisteredOnly (), DebuggerStepThrough (), ImmutableObject (True)> Открытый не наследуемый класс eAuthenticationMethod наследует StringEnumBase (Of eAuthenticationMethod)

Private Sub New(ByVal StrValue As String)
  MyBase.New(StrValue)   
End Sub

< Description("Use User Password Authentication")> Public Shared ReadOnly UsernamePassword As New eAuthenticationMethod("UP")   

< Description("Use Windows Authentication")> Public Shared ReadOnly WindowsAuthentication As New eAuthenticationMethod("W")   

Конечный класс

И теперь вы можете использовать этот класс так же, как если бы вы использовали enum: eAuthenticationMethod.WindowsAuthentication, и это по сути было бы похоже на присвоение ' W ' логического значения WindowsAuthentication (внутри перечисления), и если бы вы просматривали это значение из свойств окно (или что-то еще, что использует свойство System.ComponentModel.Description), вы получите « Использовать проверку подлинности Windows ».

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

Ando
источник
0
(MyColours)Enum.Parse(typeof(MyColours), "red", true); // MyColours.Red
(int)((MyColours)Enum.Parse(typeof(MyColours), "red", true)); // 0
Сандип Шехават
источник
-1

Возможно, вы также захотите ознакомиться с некоторыми предложениями в этом блоге: Мой новый маленький друг, Enum <T>

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

MyColours colour = Enum<MyColours>.Parse(stringValue); 

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

Джулиан Мартин
источник
Ссылка на пост не работает.
Мачадо