26

列挙値を人間が読める値に変換する方法を知っている人はいますか?

例えば:

ThisIsValueA は「これは値 A です」である必要があります。

4

8 に答える 8

18

これを、特定の Ian Horwill がずっと前にブログ投稿に残した vb コード スニペットから変換する...以来、私はこれを本番環境で正常に使用しています。

    /// <summary>
    /// Add spaces to separate the capitalized words in the string, 
    /// i.e. insert a space before each uppercase letter that is 
    /// either preceded by a lowercase letter or followed by a 
    /// lowercase letter (but not for the first char in string). 
    /// This keeps groups of uppercase letters - e.g. acronyms - together.
    /// </summary>
    /// <param name="pascalCaseString">A string in PascalCase</param>
    /// <returns></returns>
    public static string Wordify(string pascalCaseString)
    {            
        Regex r = new Regex("(?<=[a-z])(?<x>[A-Z])|(?<=.)(?<x>[A-Z])(?=[a-z])");
        return r.Replace(pascalCaseString, " ${x}");
    }

('using System.Text.RegularExpressions;' が必要です)

したがって:

Console.WriteLine(Wordify(ThisIsValueA.ToString()));

戻ってくるだろう、

"This Is Value A".

これは、Description 属性を提供するよりもはるかに単純で冗長性が低くなります。

属性は、間接的なレイヤーを提供する必要がある場合にのみここで役立ちます (質問では求められませんでした)。

于 2008-08-17T13:10:20.513 に答える
12

Enums の .ToString は C# では比較的遅く、GetType().Name に匹敵します (カバーの下で使用することさえあります)。

ソリューションが非常に高速または非常に効率的である必要がある場合は、変換を静的辞書にキャッシュして、そこから検索するのが最善の方法です。


C#3 を利用するための @Leon のコードの小さな適応。これは、列挙型の拡張として理にかなっています。それらすべてを混乱させたくない場合は、これを特定の型に制限できます。

public static string Wordify(this Enum input)
{            
    Regex r = new Regex("(?<=[a-z])(?<x>[A-Z])|(?<=.)(?<x>[A-Z])(?=[a-z])");
    return r.Replace( input.ToString() , " ${x}");
}

//then your calling syntax is down to:
MyEnum.ThisIsA.Wordify();
于 2008-08-17T16:05:16.417 に答える
5

私が見たほとんどの例では、列挙値を [Description] 属性でマークアップし、リフレクションを使用して値と説明の間で「変換」を行います。これに関する古いブログ記事は次のとおりです。

http://geekswithblogs.net/rakker/archive/2006/05/19/78952.aspx

于 2008-08-17T12:28:36.230 に答える
4

System.Reflection の「Attribute」クラスから継承して、独自の「Description」クラスを作成できます。このように(ここから):

using System;
using System.Reflection;
namespace FunWithEnum
{
    enum Coolness : byte
    {
        [Description("Not so cool")]
        NotSoCool = 5,
        Cool, // since description same as ToString no attr are used
        [Description("Very cool")]
        VeryCool = NotSoCool + 7,
        [Description("Super cool")]
        SuperCool
    }
    class Description : Attribute
    {
        public string Text;
        public Description(string text)
        {
            Text = text;
        }
    }
    class Program
    {
        static string GetDescription(Enum en)
        {
            Type type = en.GetType();
            MemberInfo[] memInfo = type.GetMember(en.ToString());
            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description), false);
                if (attrs != null && attrs.Length > 0)
                    return ((Description)attrs[0]).Text;
            }
            return en.ToString();
        }
        static void Main(string[] args)
        {
            Coolness coolType1 = Coolness.Cool;
            Coolness coolType2 = Coolness.NotSoCool;
            Console.WriteLine(GetDescription(coolType1));
            Console.WriteLine(GetDescription(coolType2));
        }
    }
}
于 2008-08-17T13:01:02.030 に答える
2

この記事もご覧ください: http://www.codeproject.com/KB/cs/enumdatabinding.aspx

具体的にはデータ バインディングに関するものですが、属性を使用して列挙値を装飾する方法を示し、属性のテキストを取得するための "GetDescription" メソッドを提供します。組み込みの説明属性を使用する際の問題は、その属性の他の使用/ユーザーが存在するため、説明が望ましくない場所に表示される可能性があることです。カスタム属性はその問題を解決します。

于 2008-08-17T13:00:10.487 に答える
0

ThisIsValueA が This_Is_Value_A になるように、enumValue.toString().Replace("_"," ") を実行できます。enumValue は変数です。

于 2008-08-17T13:57:07.190 に答える