1. 程式人生 > >【轉】編寫高質量代碼改善C#程序的157個建議——建議8: 避免給枚舉類型的元素提供顯式的值

【轉】編寫高質量代碼改善C#程序的157個建議——建議8: 避免給枚舉類型的元素提供顯式的值

bsp clas val () spa true tel str none

建議8: 避免給枚舉類型的元素提供顯式的值

一般情況下,沒有必要給枚舉類型的元素提供顯式的值。創建枚舉的理由之一,就是為了代替使用實際的數值。不正確地為枚舉類型的元素設定顯式的值,會帶來意想不到的錯誤。

如果為建議7中的枚舉類型Week增加一個元素,代碼如下所示:

    enum Week  
    {  
        Monday = 1,  
        Tuesday = 2,  
        ValueTemp,  
        Wednesday = 3,  
        Thursday = 4,  
        Friday = 5,  
        Saturday 
= 6, Sunday = 7 }

設想一下ValueTemp的值會是什麽?為了驗證結果,我們來看這段代碼的輸出:

    Week week = Week.ValueTemp;  
    Console.WriteLine(week);  
    Console.WriteLine(week == Week.Wednesday); 

輸出為:

    Wednesday  
    True 

很遺憾,我們明明為Week賦值為ValueTemp,可是得到的結果卻是Wednesday。

事實上,如果為枚舉類型顯式地賦過值,那麽很有可能在下個版本中,你為了某些增加的需要,會為枚舉添加元素,在這個時候,就像我們為Week增加元素ValueTemp一樣,極有可能會一不小心增加一個無效值。

上一個建議中已經講到如果沒有為元素顯式賦值,編譯器會逐個為元素的值+1。當編譯器發現元素ValueTemp的時候,它會自動在Tuesday = 2的基礎上+1,所以,實際ValueTemp的值和Wednesday的值都是3。而枚舉本身所包括的枚舉元素都是值類型,所以產生了上面的輸出。

從上面的例子我們應該已經註意到,枚舉元素允許設定重復的值。所以,當我們看到下面這段代碼的輸出時,應該不會感到吃驚:

    enum Temp  
    {  
        Value1 = 1,  
        Value2 = 1 
    }  
    private static void
NewMethod2() { Temp temp1 = Temp.Value1; Temp temp2 = Temp.Value2; Console.WriteLine(temp1 == temp2); Console.WriteLine(temp1.Equals(temp2)); Console.WriteLine(temp1.CompareTo(temp2)); Console.WriteLine(temp1 == Temp.Value1); Console.WriteLine(temp1 == Temp.Value2); }

輸出為:

    True  
    True  
    0  
    True  
    True 

註意 本建議也有例外。例如,當為一個枚舉類型指定System.FlagsAttribute 屬性時,就意味著可以對這些值執行 AND、OR、NOT 和 XOR 按位運算,這樣一來,就要求枚舉的每個元素的值都是 2 的若幹次冪,指數依次遞增。如Week的版本就應該為:

    [Flags]  
    enum Week  
    {  
        None = 0x0,  
        Monday = 0x1,  
        Tuesday = 0x2,  
        Wednesday = 0x4,  
        Thursday = 0x8,  
        Friday = 0x10,  
        Saturday = 0x20,  
        Sunday = 0x40 
    }  
     
    class MyClass  
    {  
        Week week = Week.Thursday | Week.Sunday;  
    }

輸出為:

Thursday, Sunday

轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技

【轉】編寫高質量代碼改善C#程序的157個建議——建議8: 避免給枚舉類型的元素提供顯式的值