4

この時点で、次のコードがあります。

internal enum Genders
{
  Male,
  Female,
  NotSure,
  Other
}

すべての値foreachし、それに基づいて文字列を返すことができるように、追加の機能を追加することを考えています。したがって、次のようにマッピングします。

Male    -> "boy"
Female  -> "girl"
NotSure -> "oh-boy"
Other   -> "cow"

列挙型をクラスにリファクタリングする必要がありますか、それとも単にToString値をさまざまな列挙型の状態に割り当てることをお勧めしますか? 私はそれをグーグルで検索しましたが、そのコード例は見られなかったので、そうすることをお勧めするかどうかはわかりません.

補助クラスを作ってこういうメソッドを使ったほうがいいのではないでしょうか?

private IEnumerable<String> GetGenders()
{
  yield return "boy";
  yield return "girl";
  yield return "oh-boy";
  yield return "cow";
}

それとも、自分を混乱させているだけで、すぐにやめるべきですか?

4

4 に答える 4

5

代わりに、Enum に拡張機能を追加することを検討してください。

たとえば、次のようにすることができます。

Gender.Male.Description (which would return string "boy")

拡張子は次のようになります。

    /// <summary>
    /// Defines an EnumExtensions type.
    /// </summary>
    public static class EnumExtensions
    {
        /// <summary>
        /// Gets the value from a DescriptionAttribute applied to the enum.
        /// </summary>
        /// <param name="value">Enum value.</param>
        /// <returns>DescriptionAttribute value, or null if no attribute is applied.</returns>
        public static string Description(this Enum value)
        {
            var type = value.GetType();
            var fieldInfo = type.GetField(value.ToString(CultureInfo.InvariantCulture));

            var descriptionAttributes = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

            return descriptionAttributes.Length > 0
                       ? ((DescriptionAttribute)descriptionAttributes[0]).Description
                       : null;
        }

列挙型は次のようになります。

public enum Gender
{
    [Description("boy")]
    Male,

    [Description("girl")]
    Female,

    [Description("oh-boy")]
    NotSure,

    [Description("cow")]
    Other
}
于 2013-01-21T09:14:43.240 に答える
1

そのような機能を追加することは合理的ですが、必ずしもあなたが提案する方法ではありません. 辞書を使用して列挙値をその翻訳にマップし、2 つのメソッドを追加します。

  1. ディクショナリで単一の列挙型を検索し、その (おそらくローカライズされた) 文字列を返すメソッド。
  2. ディクショナリ内のすべての値を IEnumerable として返す別のメソッド。

列挙型のすべての文字列のリストが必要な場合は、特定の列挙型も検索する可能性が非常に高いと思います。両方のメソッドが必要な場合は、enum 文字列のリストを 1 つ実装して、2 つのメソッドが同期しなくなることがないようにし、(もちろん) 自分自身を繰り返さないようにする必要があります。

(組み込みの enum.ToString() は「プログラマー言語」であり、さらにローカライズされていないため、ユーザーに表示できる列挙型を文字列にマップする必要があります。)

于 2013-01-21T09:13:10.563 に答える
1

まあ、それはあなたの個人的な好みとアプリケーションの要件に依存します. 列挙型の大きな利点の 1 つは、コンパイラや開発環境でさえ認識できる限定された数値セットを定義し、それらを文字列のコレクションに置き換えるとそれが無効になることです。これは、ある時点で列挙値をデータベース フィールドに格納する場合にも重要です。

パフォーマンスが大きな問題でない場合は、列挙型を で装飾して、DescriptionAttributesそれらを文字列名または必要なその他のメタデータに関連付けることができます。

internal enum Genders
{
  [Description("boy")]
  Male,
  [Description("girl")]
  Female,
  [Description("oh-boy")]
  NotSure,
  [Description("cow")]
  Other
}

...そして、必要に応じてリフレクションを使用して説明を取得します。超高速ではありませんが、WPF フォームで表示されるラベルを使用してかなり頻繁にこれを行います。ここでは、ほんの一握りのGetCustomAttributes()呼び出しがパフォーマンスの懸念事項として最も少ないものです。:)

凝ったものにしたい場合、このアプローチの利点の 1 つは (ハードコードされた文字列とは対照的に)、説明をアプリケーション リソースに含まれる文字列に関連付けることができることです (たとえば、さまざまな言語用にローカライズされたバージョンを作成できます)。 . Microsoft は、一部のライブラリでこのアプローチを採用していると思います (または、別のことを考えているのでしょうか?)。もちろんToString()、列挙値を呼び出すだけで、コードで定義されている列挙メンバーの名前を取得できます。

メソッドを使用して列挙型のメンバーを列挙することもできますEnum.GetValues()。つまり、探していることはどちらの方法でも実行できます。物事を複雑にするか、シンプルにするかがあなたにとって価値があるかどうかの問題です。

于 2013-01-21T09:24:18.283 に答える
0

実装する必要がある複雑さのレベルによって異なります。英語での説明だけの場合は、他の回答で提案されているように DescriptionAttributes を使用できます。複数の言語をサポートする必要がある場合は、ローカリゼーション リソース (.resx ファイルまたはデータベースのいずれか) を使用する必要があります。たとえば、http://www.codeproject.com/Articles/19953/Localizing-NET-Enumsを参照してください。

ただし、より複雑なシナリオでは、enum を使用するだけでは不十分です。

列挙にはいくつかの問題があります。 

  • 列挙に関連する動作がアプリケーション全体に散らばる
  • 新しい列挙値にはショットガン手術が必要です
  • 列挙型は開閉原理に従っていません

http://lostechies.com/jimmybogard/2008/08/12/enumeration-classes/より)

   

ブログ投稿の Enumeration クラスでは、パブリック抽象クラスの Enumeration と、そこから派生したクラスを作成する方法について説明しました。

于 2013-04-07T21:46:25.533 に答える