もう一つの Enum

id:siokoshou:20080127:p2 の菊池さんのコメントを受けて、速度を改善した Enum を考えてみたんですが、これでいいような気がしました。

public static class Enum<T> where T : struct
{
  private readonly static T[] values;
  private readonly static string[] strings;

  static Enum()
  {
    Debug.Assert( typeof( T ).IsEnum );
    Debug.Assert( !Attribute.IsDefined( typeof( T ),
      typeof( FlagsAttribute ) ) ); // 1/28追加
    values  = Enum.GetValues( typeof( T ) ).Cast<T>().ToArray();
    strings = Enum.GetNames(  typeof( T ) );
    Array.Sort<string, T>( strings, values ); // 1/28追加
  }

  public static T Parse( string value )
  {
    int n = Array.IndexOf<string>( strings, value );
    if ( n < 0 )
      throw new ArgumentException();
    return values[ n ];
  }

  public static IEnumerable<T> GetValues()
  {
    foreach ( var item in values )
    {
      yield return item;
    }
  }
}

GetValues() を IEnumerable にしたのは id:ladybug さんの id:ladybug:20061212 を参考にさせていただきました。
手元では100万回ループで試すと10数倍速いです。キャッシュ用にメモリを食うのが嫌ですが…。あ、今気づいたけど Dictionary 使えばもっと簡単だったかも。

(追記)菊池さんのコメントを受けて2行追加。