文字列または整数で列挙値を取得する方法


108

enum文字列またはenumint値がある場合、どうすればenum値を取得できますか。例:次のような列挙型がある場合:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

そして、いくつかの文字列変数では、次のように値「value1」があります。

string str = "Value1" 

またはいくつかのint変数で私は次のような値2を持っています

int a = 2;

列挙型のインスタンスを取得するにはどうすればよいですか?列挙型と入力文字列またはint値を指定して列挙型インスタンスを取得できる汎用メソッドが必要です。


回答:


210

いいえ、一般的なメソッドは必要ありません。これははるかに簡単です:

MyEnum myEnum = (MyEnum)myInt;

MyEnum myEnum = (MyEnum)Enum.Parse(typeof(MyEnum), myString);

それも速くなると思います。


これは実際にはこれを行う正しい方法です。IParsableインターフェースがないのと同じ理由で、型を解析する一般的な方法はありません。
ヨハネス

1
@ヨハネスそれはどういう意味ですか?一般的な方法があります。私の答えや他の人も参照してください。
Sriram Sakthivel 2014年

1
@SriramSakthivel OPが説明する問題は、KendallFreyが示したように解決されます。一般的な解析は実行できません-ここを参照してください:informit.com/blogs/blog.aspx?uk = Why - no - IParseable - interface。他のソリューションは、C#の「オンボード」ソリューションと比較して利点がありません。最大値はICanSetFromString <T>で、オブジェクトを作成してデフォルト(T)に初期化し、次のステップで代表的な文字列を渡します。これはOPが出した答えに近いですが、通常これは設計上の問題であり、システム設計のより大きなポイントが見落とされていたため、意味がありません。
ヨハネス

この答えは、特にintとstringの使用法の複数の例で非常にうまく機能しました。ありがとうございました。
テルマト2015年

1
これは今は機能していると思いますが、もう少し簡潔です。Enum.Parse<MyEnum>(myString);
Phil B

32

これを行うには多くの方法がありますが、簡単な例が必要な場合は、これで十分です。型の安全性や無効な構文解析などをチェックするために必要な防御コーディングで拡張する必要があります。

    /// <summary>
    /// Extension method to return an enum value of type T for the given string.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this string value)
    {
        return (T) Enum.Parse(typeof(T), value, true);
    }

    /// <summary>
    /// Extension method to return an enum value of type T for the given int.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this int value)
    {
        var name = Enum.GetName(typeof(T), value);
        return name.ToEnum<T>();
    }

17

TryParseorParseToObjectメソッドを使用すると、はるかに簡単になる可能性があります。

public static class EnumHelper
{
    public static  T GetEnumValue<T>(string str) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }
        T val;
        return Enum.TryParse<T>(str, true, out val) ? val : default(T);
    }

    public static T GetEnumValue<T>(int intValue) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }

        return (T)Enum.ToObject(enumType, intValue);
    }
}

コメントで@chrfinが指摘しているようthisに、パラメータタイプの前に追加するだけで、非常に簡単に拡張メソッドにすることができます。これは便利です。


2
ここでthis、パラメーターにaを追加してEnumHelper静的にし、拡張機能としても使用できます(私の回答を参照してください。ただし、残りのコードはより適切で完全です)...
Christoph Fink 2014年

@chrfin良い考えですが、スコープ内に名前空間がある場合に必要とされないインテリセンスでポップされるため、私はそれを好みません。迷惑になると思います。
Sriram Sakthivel 2014年

1
@chrfinコメントをありがとう、私の答えにメモとして追加されました。
Sriram Sakthivel 2014年

5

以下は、文字列で列挙値を取得するC#のメソッドです。

///
/// Method to get enumeration value from string value.
///
///
///

public T GetEnumValue<T>(string str) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];
    if (!string.IsNullOrEmpty(str))
    {
        foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
        {
            if (enumValue.ToString().ToUpper().Equals(str.ToUpper()))
            {
                val = enumValue;
                break;
            }
        }
    }

    return val;
}

以下は、intによって列挙値を取得するC#のメソッドです。

///
/// Method to get enumeration value from int value.
///
///
///

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];

    foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
    {
        if (Convert.ToInt32(enumValue).Equals(intValue))
        {
            val = enumValue;
            break;
        }             
    }
    return val;
}

次のような列挙型がある場合:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

その後、私は上記の方法を次のように利用できます

TestEnum reqValue = GetEnumValue<TestEnum>("Value1");  // Output: Value1
TestEnum reqValue2 = GetEnumValue<TestEnum>(2);        // OutPut: Value2

これがお役に立てば幸いです。


4
また、これを入手した場所のリファレンスを提供していただけますか?
JonH 2014年

これをコンパイルするには、最初の行をpublic T GetEnumValue <T>(int intValue)に変更する必要がありました。ここでT:struct、IConvertible最後に余分な「}」があることに注意してください
Avi

3

ジェネリック型の定義を忘れたと思います。

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible // <T> added

そして、あなたはそれを例えば次のように最も便利になるように改善することができます:

public static T ToEnum<T>(this string enumValue) : where T : struct, IConvertible
{
    return (T)Enum.Parse(typeof(T), enumValue);
}

その後、あなたはすることができます:

TestEnum reqValue = "Value1".ToEnum<TestEnum>();

2

このようなものを試してください

  public static TestEnum GetMyEnum(this string title)
        {    
            EnumBookType st;
            Enum.TryParse(title, out st);
            return st;          
         }

だからあなたはすることができます

TestEnum en = "Value1".GetMyEnum();

2

SQLデータベースから次のような列挙型を取得します。

SqlDataReader dr = selectCmd.ExecuteReader();
while (dr.Read()) {
   EnumType et = (EnumType)Enum.Parse(typeof(EnumType), dr.GetString(0));
   ....         
}

2

これを試してみてください

それは別の方法です

public enum CaseOriginCode
{
    Web = 0,
    Email = 1,
    Telefoon = 2
}

public void setCaseOriginCode(string CaseOriginCode)
{
    int caseOriginCode = (int)(CaseOriginCode)Enum.Parse(typeof(CaseOriginCode), CaseOriginCode);
}

0

文字列/値を取得する例を次に示します

    public enum Suit
    {
        Spades = 0x10,
        Hearts = 0x11,
        Clubs = 0x12,
        Diamonds = 0x13
    }

    private void print_suit()
    {
        foreach (var _suit in Enum.GetValues(typeof(Suit)))
        {
            int suitValue = (byte)(Suit)Enum.Parse(typeof(Suit), _suit.ToString());
            MessageBox.Show(_suit.ToString() + " value is 0x" + suitValue.ToString("X2"));
        }
    }

    Result of Message Boxes
    Spade value is 0x10
    Hearts value is 0x11
    Clubs value is 0x12
    Diamonds value is 0x13

0

これを行うには、次の方法を使用できます。

public static Output GetEnumItem<Output, Input>(Input input)
    {
        //Output type checking...
        if (typeof(Output).BaseType != typeof(Enum))
            throw new Exception("Exception message...");

        //Input type checking: string type
        if (typeof(Input) == typeof(string))
            return (Output)Enum.Parse(typeof(Output), (dynamic)input);

        //Input type checking: Integer type
        if (typeof(Input) == typeof(Int16) ||
            typeof(Input) == typeof(Int32) ||
            typeof(Input) == typeof(Int64))

            return (Output)(dynamic)input;

        throw new Exception("Exception message...");
    }

注:この方法はサンプルであり、改善することができます。

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