Tを列挙型に制限するジェネリックメソッドを作成する 質問する

Tを列挙型に制限するジェネリックメソッドを作成する 質問する

Enum.Parse私は、概念を拡張する機能を構築しています

  • Enum値が見つからない場合にデフォルト値を解析できるようにします
  • 大文字と小文字は区別されません

そこで私は次のように書きました。

public static T GetEnumFromString<T>(string value, T defaultValue) where T : Enum
{
    if (string.IsNullOrEmpty(value)) return defaultValue;
    foreach (T item in Enum.GetValues(typeof(T)))
    {
        if (item.ToString().ToLower().Equals(value.Trim().ToLower())) return item;
    }
    return defaultValue;
}

エラー「制約は特殊クラスにできません」が発生しますSystem.Enum

それは結構ですが、Generic Enum を許可する回避策はありますか。それとも、Parse関数を模倣して型を属性として渡す必要があり、その結果、醜いボックス化要件がコードに強制されることになりますか。

編集以下のすべての提案は非常にありがたく思っています。ありがとうございます。

落ち着きました(大文字と小文字を区別しないようにループを残しました - XML を解析するときにこれを使用しています)

public static class EnumUtils
{
    public static T ParseEnum<T>(string value, T defaultValue) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum) throw new ArgumentException("T must be an enumerated type");
        if (string.IsNullOrEmpty(value)) return defaultValue;

        foreach (T item in Enum.GetValues(typeof(T)))
        {
            if (item.ToString().ToLower().Equals(value.Trim().ToLower())) return item;
        }
        return defaultValue;
    }
}

編集: (2015年2月16日) Christopher Currensが投稿しましたMSIL または F# でのコンパイラ強制型安全な汎用ソリューション以下に、一見の価値がある、そして賛成票を投じる価値のあるコメントがあります。解決策がページのさらに上の方に浮かび上がってきたら、この編集を削除します。

編集 2: (2021 年 4 月 13 日) これは C# 7.3 以降で対処され、サポートされているため、受け入れられた回答を変更しましたが、学術的および歴史的な興味のために、上位の回答を完全に精査する価値はあります :)

ベストアンサー1

EnumType はインターフェースを実装するためIConvertible、より良い実装は次のようになります。

public T GetEnumFromString<T>(string value) where T : struct, IConvertible
{
   if (!typeof(T).IsEnum) 
   {
      throw new ArgumentException("T must be an enumerated type");
   }

   //...
}

これにより、 を実装する値型の受け渡しが引き続き許可されますIConvertible。ただし、その可能性はまれです。

おすすめ記事