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、何年も前に私がこれを尋ねたとき、それは見つかりませんでした。重複として閉じることに投票しました。
Matt Clarkson、

回答:


381

System.Enum.Parseを確認してください。


enum Colors {Red, Green, Blue}

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


72
あなたはそれが「真」であることを第三のオプションパラメータを渡すことによって大文字と小文字の区別を無視することができます忘れてはいけない
好気性

まさに私が探していたもの!乾杯!
Zame

11
@ user1531040実際には、Enum.TryParseがあります。
DarLom

入力が数値の場合、列挙の解析は常に「成功」​​することに注意してください。解析された数値を返すだけで、それが列挙型にキャストされます。したがって、一部のユーザー入力が有効な列挙型かどうかを確認する場合は、最初に数値の内容を確認する必要があります。有効な列挙型を返しますが、定義された列挙型名にはまったく存在しない可能性がある値を含むため、非常に奇妙な問題が発生する可能性があります。
Nyerguds

19

intを列挙型にキャストできます

(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にキャストして、int値からenum値を取得できます。

このように、例えば:

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をスローします。関数内でキャッチしてデフォルト値を返すことができます。


注:Colinの回答に示されているように、Enum.GetValuesである必要があります。
OregonGhost

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

これもコンパイルされません。ジェネリックParseメソッドはありません。
ジョアンMenighin

コンパイルして動作しました。多分それはあなたが使用しているバージョンに依存しますか?私は.NET core 3.1を使用しています
Vinni

0

以前の回答で述べたように、基になるデータ型(int-> enum型)または解析(string->列挙型)に直接キャストできます。

ただし、注意してください。列挙型には.TryParseがないため、失敗をキャッチするには、解析の周りにtry / catchブロックが必要になります。


3
この質問が尋ねられる前はありませんでしたが、.NET 4の時点であります!msdn.microsoft.com/en-us/library/system.enum.tryparse.aspx。Enum.TryParse <MyColour>( "Red"、out color)のようなものになります
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#にはこの機能が組み込まれています。
Artemix

これは質問に対する答えですか?はるかに簡単なコードについては他の回答を見てください
Firo

0

(これまでに提供された有効で良い回答に加えて)あなたに役立つかもしれない1つのことは、ここで提供されているStringEnumのアイデアです。

これにより、列挙をクラスとして定義できます(例はvb.netにあります)。

<StringEnumRegisteredOnly()、DebuggerStepThrough()、ImmutableObject(True)> Public NotInheritable Class eAuthenticationMethod 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")   

終了クラス

そして今、あなたは列挙型を使用するのと同じようにこのクラスを使用することができます:eAuthenticationMethod.WindowsAuthenticationそしてこれは本質的に ' W 'に(列挙型内の)WindowsAuthenticationの論理値を割り当てるようなものであり、プロパティからこの値を表示する場合ウィンドウ(またはSystem.ComponentModel.Descriptionプロパティを使用する他の何か)は、「Windows認証を使用する」と表示されます。

私はこれを長い間使用しており、意図的にコードをより明確にします。



-1

このブログ投稿のいくつかの提案を確認することもできます: 私の新しい小さな友達、Enum <T>

この投稿では、非常にシンプルなジェネリックヘルパークラスを作成して、固有の醜いキャスト構文を回避できるようにする方法について説明Enum.Parseしています。

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

または、同じ方法で拡張メソッドを使用して同様のことを実現することについて説明している同じ投稿のコメントのいくつかをチェックしてください。


投稿リンクが壊れています。
マチャド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.