【轉】編寫高質量代碼改善C#程序的157個建議——建議8: 避免給枚舉類型的元素提供顯式的值
建議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 voidNewMethod2() { 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: 避免給枚舉類型的元素提供顯式的值