2012-01-17 24 views
2

我有一個枚舉,假設它被稱爲體育:枚舉擴展方法來清除就地

enum Sports 
{ 
    Baseball = 1, 
    Basketball = 2, 
    Football = 4, 
    Hockey = 8, 
    Soccer = 16, 
    Tennis = 32, 
    etc... 
} 

我基本上會想補充一點清除面具有點像這樣的擴展方法:

Sports Mask = Sports.Baseball | Sports.Football | Sports.Tennis; //37 
Mask.Clear(Sports.Baseball); 
// Mask = Football | Tennis 

這是我提出的擴展方法,它不起作用。清除不會影響Mask,值仍然爲37.我不確定我是否可以在擴展方法內修改此部分。有沒有其他的方法來完成這個?

public static void Clear<T>(this Enum value, T remove) 
{ 
    Type type = value.GetType(); 
    object result; 

    if (type.Equals(typeof(ulong))) 
    { 
    result = Convert.ToUInt64(value) & ~Convert.ToUInt64((object)remove); 
    } 
    else 
    { 
    result = Convert.ToInt64(value) & ~Convert.ToInt64((object)remove); 
    } 

    value = (Enum)Enum.Parse(type, result.ToString()); 
} 
+0

作爲請注意,如果您打算通過字符串表示形式顯示枚舉,那麼這是一個很好的選擇a將'[flags]'屬性添加到枚舉定義中。爲了一個很好的解釋檢查這個答案:http://stackoverflow.com/questions/8447/enum-flags-attribute/8480#8480 –

+0

謝謝。我在我的真實代碼中有[Flags]標籤,但我一起快速入侵它,然後當我運行我的示例時,我喜歡「爲什麼它不顯示實際值,而不是37」,那麼我就像「哦」 「我忘了[標誌]。 – Mark

回答

3

因爲枚舉是值類型,所以只修改參數。您可以返回修改後的值並將其分配給原始變量。

public static T Clear<T>(this Enum value, T remove) { ... } 
mask = mask.Clear(Sports.Baseball); 
//just like 
//DateTime dt = DateTime.Now; 
//dt = dt.AddHour(1); 

順便說一下,我不認爲這裏值得一個擴展方法。爲什麼不只是簡單地使用:

mask = mask & ~Sports.BaseBall; 
mask = mask & ~anotherMask; 

你的擴展方法是非常低效的,因爲(un)裝箱。

+0

在你看來,延伸方法比只做Mask&=〜Sports.Baseball更好或更差。感謝您的答案btw。編輯:你在編輯中回答我的問題,因爲我沒有刷新。謝謝。 – Mark

0

您要求通過引用將實例傳遞給擴展方法。 But you can't do this in C#

+0

謝謝,這或多或少是我懷疑的,但想知道是否有內置的方式。 – Mark

1

克齊斯茨托夫·克瓦林納在MSDN博客介紹瞭如何在低於2個鏈接清除枚舉使用Flags屬性Enum值:

http://blogs.msdn.com/b/kcwalina/archive/2006/08/29/clearingflagenum.aspx

http://weblogs.asp.net/bhouse/archive/2006/08/29/Clearing-Enum-Flags.aspx

樣品:

[Flags] 
public enum Foos { 
    A = 1, 
    B = 2, 
    C = 4, 
    D = 8, 
    AB = A | B, 
    CD = C | D, 
    All = AB | CD 
} 

static class Program { 
    static void Main() { 
     Foos value = Foos.AB; 
     Console.WriteLine(ClearFlag(value,Foos.A); 
    } 
    public static Foos ClearFlag(Foos value, Foos flag) { 
     return value & ~flag; 
    } 
}