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

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

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

Ответ 1

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


enum Colors {Red, Green, Blue}

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

Ответ 2

Вы можете преобразовать int в enum

(MyColour)2

Существует также опция Enum.Parse

(MyColour)Enum.Parse(typeof(MyColour), "Red")

Ответ 3

Все, что вам нужно, это Enum.Parse.

Ответ 4

Я отметил ответ 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;
}

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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

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

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

Ответ 8

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);
        }
    }
}

Ответ 9

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

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

< StringEnumRegisteredOnly(), DebuggerStepThrough(), ImmutableObject (True) > Открытый класс NotInheritable eAuthenticationMethod Наследует StringEnumBase (из 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")   

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

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

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

Ответ 10

(MyColours)Enum.Parse(typeof(MyColours), "red", true); // MyColours.Red
(int)((MyColours)Enum.Parse(typeof(MyColours), "red", true)); // 0