web-dev-qa-db-ja.com

文字列としてのC#数値列挙値

私は次の列挙型を持っています:

public enum Urgency {
    VeryHigh = 1,
    High     = 2,
    Routine  = 4
}

enum "value" as stringを次のように取得できます。

((int)Urgency.Routine).ToString() // returns "4"  

注:これは次のものとは異なります。

Urgency.Routine.ToString() // returns "Routine"
(int)Urgency.Routine       // returns 4

いくつかの構文上の砂糖を提供する拡張クラスまたは静的ユーティリティクラスを作成する方法はありますか? :)

55
David Moorhouse

Enums ToStringメソッドのオーバーロードを使用してフォーマット文字列を与えることができるはずです。これにより、enumの値が文字列として出力されます。

public static class Program
{
    static void Main(string[] args)
    {
        var val = Urgency.High;
        Console.WriteLine(val.ToString("D")); 
    }
}

public enum Urgency 
{ 
    VeryHigh = 1,
    High = 2,
    Low = 4
}
101
Scott Bartlett

列挙型の「人間が読める」説明(例では「非常に高い」ではなく「非常に高い」)を実現するために、列挙型の値を次のように属性で装飾しました。

public enum MeasurementType
{
    Each,

    [DisplayText("Lineal Metres")]
    LinealMetre,

    [DisplayText("Square Metres")]
    SquareMetre,

    [DisplayText("Cubic Metres")]
    CubicMetre,

    [DisplayText("Per 1000")]
    Per1000,

    Other
}


public class DisplayText : Attribute
{

    public DisplayText(string Text)
    {
        this.text = Text;
    }


    private string text;


    public string Text
    {
        get { return text; }
        set { text = value; }
    }
}

次に、次のような拡張メソッドを使用しました。

    public static string ToDescription(this Enum en)
    {

        Type type = en.GetType();

        MemberInfo[] memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {

            object[] attrs = memInfo[0].GetCustomAttributes(
                                          typeof(DisplayText),

                                          false);

            if (attrs != null && attrs.Length > 0)

                return ((DisplayText)attrs[0]).Text;

        }

        return en.ToString();

    }

その後、電話するだけです

myEnum.ToDescription()
23
Stuart Helwig

この列挙型だけを扱いたい場合は、Mark Byerのソリューションを使用してください。

より一般的なソリューションの場合:

public static string NumberString(this Enum enVal) 
{
    return Convert.ToDecimal(enVal).ToString("0");
}

10進数に変換すると、8つの異なる許可された整数型を明示的に処理する必要がなくなります。それらはすべて10進数に無損失で変換されますが、相互に変換されないためです残りすべて)。これを行うとおそらく高速になりますが(特に、比較の順序で適切に選択した場合)、比較的少ないゲインでより冗長になります。

編集:

上記はフランケントッシュほど良くありませんが、フランケントッシュは問題を真の問題に突き止め、非常に雄弁に解決します。

4
Jon Hanna

少し考えてみてはいかがですか?基礎となるすべてのタイプで動作するはずです。

public static class EnumTools
{
    public static string ToRawValueString(this Enum e)
    {
        return e
            .GetType()
            .GetFields(BindingFlags.Public | BindingFlags.Static)
            .First(f => f.Name==e.ToString())
            .GetRawConstantValue()
            .ToString();
    }
}

次に:

Console.WriteLine(Urgency.High.ToRawValueString()); //Writes "2"
3
spender

素晴らしいもの...私は今、私のプロジェクトに拡張メソッドを追加しました

_public static class EnumExtensions 
{ 
    public static string NumberString(this Enum enVal) 
    { 
        return enVal.ToString("D"); 
    }
} 
_

これで、Urgency.Routine.NumberString();を呼び出して、int値を文字列として取得できます。FrankentoshとJonに感謝します:)

3
David Moorhouse

必要に応じて、すべての列挙型に対して拡張メソッドを機能させることができます。

public static string ToValueString(this Enum enumValue) 
{
    if (enumValue.GetType().GetEnumUnderlyingType() == typeof(int))
        return ((int)(object)enumValue).ToString();
    else if (enumValue.GetType().GetEnumUnderlyingType() == typeof(byte))
        return ((byte)(object)enumValue).ToString();
    ... 
}        
2
Kirk Woll

特定のタイプの拡張メソッドを作成できます。

public static class UrgencyExtension
{
    public static string ToIntegerString(this Urgency u)
    {
        return ((int)u).ToString();
    }
}

次のように使用します。

Urgency u = Urgency.Routine;
string s = u.ToIntegerString();
2
Mark Byers

簡単なアプローチ

((Urgency)4).ToString() // returns "Routine"
1
Lauda Wang