2011-02-09 17 views
1

私は、フラグ付きenum値のユーティリティ拡張メソッドを作成しようとしています。このメソッドの目的は、現在有効になっているすべてのフラグのリストを取得することです。ジェネリック医薬品は、以下に頼ら私が持っていたenum型では動作しないため、しかしEnumメソッドを使用して一般的なメソッドを制約するT

public static IEnumerable<T> GetFlags<T>(this T value) where T:Enum 
    { 
    return Enum.GetValues(typeof(T)).OfType<Enum>().Where(value.HasFlag).Cast<T>(); 
    } 

public static IEnumerable<T> GetFlags<T>(this Enum value) 
    { 
    return Enum.GetValues(typeof(T)).OfType<Enum>().Where(value.HasFlag).Cast<T>(); 
    } 

は、どのような方法があり、私がやりたいこと

このでしたこれを回避するには、メソッドが呼び出されるたびに型を宣言しなければならないと自分自身を辞めるべきですか?

+0

http://stackoverflow.com/questions/1331739/enum-type-constraints-in-cの – SLaks

+0

が重複する可能性(HTTP [誰でも列挙型の一般的な制約の欠如のために良い回避策を知っていますか?]: //stackoverflow.com/questions/7244/anyone-know-a-good-workaround-for-the-lack-of-an-enum-generic-constraint) – nawfal

答えて

2

あなたができることは、where T : structです。あなたは、あなたがプライベートコンストラクタとEnumなどTempと公共のネストされた抽象継承したクラスをEnums<Temp>与えることができますしたい場合は

public abstract class Enums<Temp> where Temp : class { 
    public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp { 
     return (TEnum)Enum.Parse(typeof(TEnum), name); 
    } 
} 
public abstract class Enums : Enums<Enum> { } 

Enums.Parse<DateTimeKind>("Local") 

、防ぐために:非拡張メソッドについては

、あなたは醜いトリックを使用することができます非enumの継承バージョン

拡張メソッドをstaticクラスで定義し、別のクラスを継承することはできないため、このトリックを使用して拡張メソッドを作成することはできません。

+1

いくつかの選択肢のように醜いわけではありません。かなり独創的な、実際に。 – Doug

0

リフレクションを使用しています。実行時に自分でHasFlag(または必要な方法)を呼び出すだけです。

where節はできるだけ多くの制約を与えます。あなたのタイプがenumでない場合、このコードはTargetInvocationExceptionを発生させます。

/// <summary> 
/// Gets the flags for the given enum value. 
/// </summary> 
/// <typeparam name="T">The enum type</typeparam> 
/// <param name="enumValue">The enum value.</param> 
/// <returns>The flagged values.</returns> 
public static IEnumerable<T> GetFlags<T>(this T enumValue) 
    where T : struct 
{ 
    Type enumType = enumValue.GetType(); 
    foreach (T value in Enum.GetValues(enumType)) 
    { 
     bool hasFlag = (bool)enumType.InvokeMember("HasFlag", BindingFlags.InvokeMethod, null, enumValue, new object[] { value }); 
     if (hasFlag) 
     { 
      yield return value; 
     } 
    } 
} 
関連する問題