2012-03-01 93 views
6

我剛剛在C#中開始使用Generics,但在早期遇到問題,如何在通用Enum上調用.HasFlag()?如何添加[Flags]屬性?具有泛型枚舉的HasFlag?

+0

總之,你不能。約束不考慮泛型參數的屬性。你必須通過反思來強制執行。 – 2012-03-01 16:07:43

+1

類型參數應該以'T'開頭;你應該把'GenericEnum'改爲'TEnum'。 – SLaks 2012-03-01 16:08:59

+0

可以舉個例子@ M.Babcock?並正式指出,@SLaks – DevDave 2012-03-01 16:11:29

回答

6

調用實例方法無論如何都需要裝箱,所以,由於您無法約束到Enum,只需放棄泛型並使用Enum即可。例如,而不是:

void Something(TEnum enumValue, TEnum flags) 
{ 
    if (enumValue.HasFlags(flags)) 
     //do something ... 
} 

這樣做:

void Something(Enum enumValue, Enum flags) 
{ 
    if (enumValue.HasFlags(flags)) 
     //do something ... 
} 

在一個通用的方法,你可以實現你的目標是這樣的:

void Something(TEnum enumValue, TEnum flags) 
{ 
    Enum castValue = (Enum)(object)enumValue; 
    Enum castFlags = (Enum)(object)flags; 

    if (castValue.HasFlags(castFlags)) 
     //do something ... 
} 

這將在運行時拋出一個異常如果您使用不是枚舉的值類型調用該方法。您也可以通過ValueType而非object投,因爲類型參數是已知的代表值類型:

Enum castValue = (Enum)(ValueType)enumValue; 
+0

我正在做你最初的建議,但我試圖重構幾個使用你的例子的方法到一個將採用泛型枚舉,仍然可以調用其上的標誌 – DevDave 2012-03-01 16:16:55

+2

@Tyler我添加了一個例子顯示如何你可以將泛型類型參數的實例轉換爲'Enum'。 – phoog 2012-03-01 16:20:42

+0

謝謝@phoog。我仍然試圖解決它,但注意到HasFlag()方法出現在intellisense中! – DevDave 2012-03-01 16:27:02