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
Enum
Type はインターフェースを実装するため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
。ただし、その可能性はまれです。