2009-03-25 12 views
21

私の質問は一例として最もよく説明されています。追加情報を.NET Enumに関連付ける

は、私が列挙型があるとします。

public enum ArrowDirection 
{ 
    North, 
    South, 
    East, 
    West 
} 

私はその方向で、各方向に対応する単位ベクトルを関連付けます。たとえば、北の場合は(0、1)、西の場合は(-1、0)を返すものが必要です。Javaでは、その機能を提供できるenumの中にメソッドを宣言できます。

私の現在の解決策は、渡されたArrowDirectionに対応するベクトルを返す静的メソッド(enumを定義するクラスの内側にあります)です(このメソッドはHashTableを使用して検索を実行しますが、 。これは...汚れているようです。

質問:
.NETの列挙型に対応する追加情報を格納するためのベストプラクティスの解決策はありますか?

答えて

37

C#3.0でこれを行うための素晴らしい新機能があります。重要なのはこの美しい事実です:列挙型は拡張メソッドを持つことができます!だから、ここで何ができるかです:

public enum ArrowDirection 
{ 
    North, 
    South, 
    East, 
    West 
} 

public static class ArrowDirectionExtensions 
{ 
    public static UnitVector UnitVector(this ArrowDirection self) 
    { 
     // Replace this with a dictionary or whatever you want ... you get the idea 
     switch(self) 
     { 
      case ArrowDirection.North: 
       return new UnitVector(0, 1); 
      case ArrowDirection.South: 
       return new UnitVector(0, -1); 
      case ArrowDirection.East: 
       return new UnitVector(1, 0); 
      case ArrowDirection.West: 
       return new UnitVector(-1, 0); 
      default: 
       return null; 
     } 
    } 
} 

、あなたはこれを行うことができます。

var unitVector = ArrowDirection.North.UnitVector(); 

スウィート!私は約1ヶ月前にこれを見つけましたが、それは新しいC#3.0機能の素晴らしい結果です。

Here's another example on my blog.

+0

それはかなりクールです。私は拡張機能について知っていましたが、enum拡張子のためにそれらを使用することは考えていませんでした –

+0

ええ、最初はどちらかです。友人はそれについて私に語った。とてもいいですね。私はまた、あなたがnull値で拡張メソッドを呼び出すことができる(最近、ここではSO)ことを知って驚いた。これは静的メソッドなので、まだ動作します。いつものように、C#チームはこれらの機能を考えて素晴らしい仕事をしてきました。 –

+0

あなたは受け入れられた答えを得るつもりです。私はそれを試して、それは完全に動作します。唯一のことは。正確にどこで列挙型を宣言すべきですか?私がクラスに残しておけば、アクセスしにくいと言います。私はそれを動作させるために "ClassName_Enums"クラスを作らなければなりませんでした。 – colithium

3

私はそれについてhereとブログしました。

Attributesでこれを試してみてください。代わりに説明

public enum Status { 

    [Status(Description = "Not Available")]  

    Not_Available = 1,  

    [Status(Description = "Available For Game")] 

    Available_For_Game = 2,  

    [Status(Description = "Available For Discussion")] 

    Available_For_Discussion = 3, 

    } 

    public class StatusEnumInfo { 

    private static StatusAttribute[] edesc; 

    public static String GetDescription(object e) 

    { 

     System.Reflection.FieldInfo f = e.GetType().GetField(e.ToString()); 

     StatusEnumInfo.edesc = f.GetCustomAttributes(typeof(StatusAttribute), false) as StatusAttribute[]; 

     if (StatusEnumInfo.edesc != null && StatusEnumInfo.edesc.Length == 1)   

     return StatusEnumInfo.edesc[0].Description; 

     else   

     return String.Empty; 

    } 

    public static object GetEnumFromDesc(Type t, string desc) 

    { 

     Array x = Enum.GetValues(t); 

     foreach (object o in x) { 

     if (GetDescription(o).Equals(desc)) { 

      return o; 

     } 

     } return String.Empty; 

    } 

    } 

    public class StatusAttribute : Attribute { 

    public String Description { get; set; } 

    } 



    public class Implemenation { 

    public void Run() 

    { 

     Status statusEnum = (Status)StatusEnumInfo.GetEnumFromDesc(typeof(Status), "Not Available"); 

     String statusString = StatusEnumInfo.GetDescription(Status.Available_For_Discussion); 

    } 

    } 

、あなたが見て可能性があり、カスタムプロパティ

0

一つは「タイプセーフ列挙」パターンで使用します。これは、あなたが実際にメソッド/プロパティは/ etc持つことができる本格的な静的オブジェクトであり、列挙型を作成することができます。..

http://www.javacamp.org/designPattern/enum.html

ジョシュア・ブロックは、彼の本の中でこのパターンを語る「有効Javaの。」私はさまざまな状況でそれを使ってきましたが、実際には単純な列挙型よりも好きです。 (これは言語に依存しません - Java、C#、またはほぼすべてのOO言語で動作します)。

+0

私はあまりにも、それのようにそれを使用しました。しかし、最近では、私がもっと好きなものを見つけました。拡張メソッドをenumに置くことができます!面白いどれくらいの楽しみは私をもたらす...それは本当にいいです。 –

+0

私はそれをチェックしなければならない、情報のおかげで –

0

あなたの静的メソッドのアプローチは私にとって非常にきれいだと思われます。 enumとstaticメソッドの両方を同じクラスにカプセル化します。列挙型への変更は、その単一クラス内で集中管理されます。

列挙型にメソッドを追加すると(Javaごとに)、実際には非常に単純な概念であるものが複雑になります。

属性ベースのアプローチは興味深いですが、静的メソッドと比較した場合、再び複雑すぎるように見えます。

1
using System.ComponentModel; 
using System.Reflection; 


public enum ArrowDirection 
{ 

[Description("Northwards")] 
North, 

[Description("Southwards")] 
South, 

[Description("Eastwards")] 
East, 

[Description("Westwards")] 
West 
} 

...

説明のリストを取得するために拡張メソッドを作成します。

public static class Enum<T> where T : struct 
{ 

    /// <summary> 
    /// Gets a collection of the enum value descriptions. 
    /// </summary> 
    /// <returns></returns> 
    public static IList<string> GetDescriptions() 
    { 
     List<string> descriptions = new List<string>(); 
     foreach (object enumValue in Enum<T>.GetValues()) 
     { 
      descriptions.Add(((Enum)enumValue).ToDescription()); 
     } 
     return descriptions; 

    } 
} 
+0

これは拡張メソッドのようには見えません。 'this'パラメータはどこにありますか?また、 'ToDescription'はどこから来ますか?それは拡張メソッドであるはずですか? – CoderDennis