Шукайте рядок у 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");


72
Не забувайте, що ви можете ігнорувати чутливість регістру, передаючи третій необов'язковий параметр, щоб бути "істинним"
Aerophilic

Саме те, що я шукав! Ура!
Замє

11
@ user1531040 Насправді є Enum.TryParse.
ДарЛом

Зауважте, що перебір перерахунків завжди "успішний", якщо вхід чисельний; він просто повертає проаналізований номер, який потім передається на тип enum. Тож якщо ви хочете перевірити, чи є якийсь користувальницький ввід дійсним перерахунком чи іншим, спершу слід перевірити чисельний вміст. Оскільки він повертає дійсну enum, але зі значенням, яке взагалі може не існувати у визначених іменах enum, ви можете отримати справді дивні проблеми.
Nyerguds

19

Ви можете кинути int на enum

(MyColour)2

Також є варіант Enum.Parse

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

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

1

Ви можете використовувати 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, якщо значення не знайдено, ви можете захопити його всередині функції та повернути значення за замовчуванням.


ПРИМІТКА. Звичайно, це мали бути Enum.GetValues, як показано у відповіді Коліна.
OregonGhost

1
var color =  Enum.Parse<Colors>("Green");

Це навіть не компілюється. Не існує родового Parseметоду.
Жоао Менігін

Він склав і працював для мене. Може, це залежить від версії, яку ви використовуєте? Я використовую .NET core 3.1
Vinni

0

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

але будьте обережні - не існує .TryParse для перерахунків, тож вам знадобиться блок "спробувати" / "ловити" навколо розбору, щоб знайти помилки.


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)> Загальнодоступний клас несерйозного eAuthenticationMenter Inherits 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 (всередині enum), і якби ви переглядали це значення з властивостей вікно (або щось інше, що використовує властивість System.ComponentModel.Description), ви отримаєте " Використовувати автентифікацію Windows ".

Я використовую це вже давно, і це робить код більш зрозумілим у намірі.



-1

Ви також можете перевірити деякі пропозиції в цій публікації в блозі: Мій новий маленький друг, Енум <T>

У публікації описаний спосіб створити дуже простий загальний клас помічників, який дозволяє вам уникнути неприємного синтаксису кастингу, властивого Enum.Parse- замість цього ви в коді пишете щось подібне:

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

Або перегляньте деякі коментарі в тому самому дописі, в яких йдеться про використання методу розширення, щоб досягти подібного.


Посилання посилання розірвано.
Мачадо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.