2016-07-05 3 views
3

enumから追加情報を保存して取得しようとしていました。私はそれのための2つの方法で終わった。 最初の方法は、カスタム属性を使用する方法です。 https://stackoverflow.com/a/22054994/5078531 https://stackoverflow.com/a/35040378/5078531enumsから追加情報を保存して読み込む効率的な方法

public class DayAttribute : Attribute 
{ 
    public string Name { get; private set; } 

    public DayAttribute(string name) 
    { 
     this.Name = name; 
    } 
} 

enum Days 
{ 
    [Day("Saturday")] 
    Sat, 
    [Day("Sunday")] 
    Sun 
} 

public static TAttribute GetAttribute<TAttribute>(this Enum value) 
     where TAttribute : Attribute 
    { 
     var enumType = value.GetType(); 
     var name = Enum.GetName(enumType, value); 
     return enumType.GetField(name).GetCustomAttributes(false).OfType<TAttribute>().SingleOrDefault(); 
    } 

私は列挙型の拡張メソッドを書くことで、ここで見つける第二の方法 。 https://stackoverflow.com/a/680515/5078531

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

public static class ArrowDirectionExtensions 
{ 
    public static UnitVector UnitVector(this ArrowDirection self) 
    {   
     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; 
     } 
    } 
} 

もし私が選ぶべき方法の性能を探していますか?または他の効率的な方法がありますか?

+3

の両方が実際に悪いです。事前定義された値を持つ構造体が必要な場合は、あらかじめ定義された値を持つスタティックな読み取り専用フィールドなど、事前定義された値を持つ構造体を使用します。 *人々が独自のインスタンスを作成するのを防ぐには、コンストラクタをprivateにしてください。 –

+1

"どのメソッドを選択するべきかを探しているのなら":どちらもありません。まず、パフォーマンスのニーズを定義する必要があります(制作作業では、「できるだけ早く」はめったに受け入れられる定義ではありません)。その場合、最も読みやすい方法を選択する必要があります。次に、ベンチマークを行う必要があります。コードのこの特定の部分がベンチマークである場合は、それを変更するか、そうでない場合は呼び出しコードを変更して呼び出し頻度を減らす必要があります。 – Brian

答えて

3

どちらも有効です。他の多くの方法があります。個人的には、最初の方が便利です。一度のみ属性を処理し、列挙型の値が連続していて0ベースの場合は、おそらく平らな配列として格納する(おそらくstaticフィールドに)ことによって、リフレクションのパフォーマンスの低下を緩和できます。さもなければ、辞書の中にあるかもしれない。

0

DayaAttributeCacheは、他の列挙型と属性型を格納できるように、より汎用的にすることができます。私はちょうどこれをキャッシュアプ​​ローチを示すために速くしました。 Enum値は0から始まる連続していなければなりませんが、必要に応じてこの値を変更することができます。このように呼び出され

public static class DaysAttributeCache 
{ 
    private static readonly string[] Cache; 

    static DaysAttributeCache() 
    { 
     Type enumType = typeof(Days); 
     Cache = new string[Enum.GetValues(enumType).Length]; 

     foreach (Enum value in Enum.GetValues(enumType)) 
     { 
      var name = Days.GetName(enumType, value); 

      DayAttribute attribute = enumType 
       .GetField(name) 
       .GetCustomAttributes(false) 
       .OfType<DayAttribute>() 
       .SingleOrDefault(); 

      string weekDay = attribute?.Name; 
      Cache[((IConvertible)value).ToInt32(CultureInfo.InvariantCulture)] = weekDay; 
     } 
    } 

    public static string GetWeekday(this Days value) 
    { 
     return Cache[(int)value]; 
    } 
    } 

...

string saturday = Days.Sat.GetWeekday(); 
関連する問題