“多态枚举”数值如何判断?
枚舉的作用就是用“字面量”的形式(附帶智能提示)取代純粹的數(shù)字化。假設(shè)某一個(gè)程序中有4盞燈,同時(shí)該程序帶有一個(gè)輸入源信號來輸入究竟是那個(gè)燈點(diǎn)亮——顯然定義一個(gè)枚舉遠(yuǎn)遠(yuǎn)勝過用數(shù)字(1,2,3,4)表示具體某個(gè)燈亮好得多。因此枚舉和數(shù)值往往是密不可分的。通常情況下枚舉第一項(xiàng)默認(rèn)是0,以后每項(xiàng)遞增1;但是某些情況下(例如“多態(tài)枚舉”——指一個(gè)枚舉值可能包含多種枚舉狀態(tài))的情況下,你完全為某些枚舉指定對應(yīng)的值,而且必須如此(理由后面說明)。譬如判斷任意一個(gè)文件在Windows下的狀態(tài)(假設(shè)3種):
[C#]
public enum FileAttributes {Normal = 1 Hidden = 1<<1 ReadOnly = 1<<2 }[VB.NET]
Public Enum FileAttributesNormal = 1 Hidden = 1<<1 [ReadOnly] = 1 << 2 End Enum之所以要為每個(gè)枚舉單獨(dú)指定對應(yīng)的數(shù)值,其原因在于一個(gè)文件不可能單獨(dú)是“一種狀態(tài)”(比如一個(gè)文本文件可能具備“隱藏”和“只讀”雙態(tài)),顯然單獨(dú)用一個(gè)枚舉值根本無法表示,而且要把每種狀態(tài)的組合列出也根本不可能;不過大家應(yīng)該清楚一點(diǎn)——那就是枚舉和數(shù)值之間的轉(zhuǎn)換關(guān)系:
1)當(dāng)把一個(gè)數(shù)字轉(zhuǎn)換成枚舉,且這個(gè)數(shù)字映射到某個(gè)特定的枚舉值,則直接輸出該枚舉值。
2)當(dāng)把一個(gè)數(shù)字轉(zhuǎn)換成枚舉,且這個(gè)數(shù)字無法映射到某個(gè)特定的枚舉值,則直接輸出該數(shù)字。
因此.net中允許枚舉進(jìn)行“與或非”的操作——其中“或”操作等同于“+”(這個(gè)枚舉不支持),把不同的枚舉映射的數(shù)值求和,那么所得到的結(jié)果自然也就是包含多個(gè)枚舉值的結(jié)果。
這樣求和有什么先決條件么?顯然是有的。因?yàn)椤盎颉边\(yùn)算是“全1得0,見1得1”(“全1”表示兩個(gè)比特位都是1,那么得到0,例如二進(jìn)制:1+1=0)。這樣的話,如果枚舉值是按照默認(rèn)的“遞增”的話,顯然會(huì)造成數(shù)據(jù)上的混亂(譬如一開始0,第二項(xiàng)1,那么“或”變成1,以后你再也推斷不出那個(gè)“0”對應(yīng)的枚舉值曾經(jīng)用過;再譬如從2開始,第二項(xiàng)3,那么“或”的結(jié)果是5,“5”的二進(jìn)制為“0000 0101",這樣的話“2”和“3”其實(shí)也就無法得到了(因?yàn)椤盎颉钡木壒蕘y套了)。
要使的其“不亂套”,唯一的方法就是每個(gè)枚舉值取“2”的N次方(理由很簡單:因?yàn)?的N次方只有特定位為1,其余均為0,這樣“或”不會(huì)導(dǎo)致“1變成0”的慘劇)。例如示例代碼中每個(gè)枚舉值都是前一次“左移一位”(本質(zhì)是2的N次方!),這樣“或”的結(jié)果是0000 0001+0000 0010=0000 0011(十進(jìn)制3)。
對于我們而言,要判斷某個(gè)“多態(tài)枚舉”是否包含特有值,只需把這個(gè)值與“特定值”進(jìn)行“與”操作(因?yàn)椤芭c”是“見0得0,全1得1”,可以屏蔽其它位而保留特定位)。之前說過“2的N次方”只有特定位是1,那么“或”之后對其“與”,則只需判斷特定位是否為1即可了。代碼如下(假設(shè)FileAttributes是一個(gè)已經(jīng)定義并且賦值的枚舉變量)。
[C#]
if(FileAttributes & FileAttributes.Hidden == File.Attributes.Hidden) {……………… }[VB.NET]
If (FileAttributes And FileAttributes.Hidden = FileAttributes.Hidden) Then………………End If
?同樣地,Enum中有一個(gè)Parse(或者TryParse)方法允許我們把枚舉名稱(或者枚舉名稱對應(yīng)的數(shù)值)轉(zhuǎn)化成相應(yīng)的枚舉類型。這里如果輸出多個(gè)枚舉,自動(dòng)做“或”運(yùn)算:
下面可以做一個(gè)實(shí)驗(yàn):
[C#]
enum Colors { None = 0, Red = 1, Green = 2, Blue = 3 };string[] colorStrings = { "Red,Green" };foreach (string colorString in colorStrings){Colors colorValue;if (Enum.TryParse(colorString, out colorValue)) Console.WriteLine(colorValue);}
[VB.NET]
Enum ColorsNone = 0
Red = 1
Green = 2
Blue = 3
End Enum
Dim colorStrings As String() = {"Red,Green"} For Each colorString As String In colorStringsDim colorValue As ColorsIf [Enum].TryParse(colorString, colorValue) ThenConsole.WriteLine(colorValue)End If Next
如果直接輸出“colorValue”,那么結(jié)果是“3”,恰恰是Red+Green的枚舉值。(是“或”關(guān)系)。
記住:“枚舉”和“數(shù)值”是一一對應(yīng)的,否則就會(huì)出現(xiàn)“張冠李戴”的錯(cuò)誤,啼笑皆非:
[C#]
public class Example {enum Colors { None = 0, Red = 1, Green = 2, Blue = 3 };public static void Main(){string[] colorStrings = { "Red,Green" };foreach (string colorString in colorStrings){Colors colorValue;if (Enum.TryParse(colorString, out colorValue)) Console.WriteLine(colorValue);}} }[VB.NET]
Public Class ExamplePrivate Enum ColorsNone = 0Red = 1Green = 2Blue = 3End EnumPublic Shared Sub Main()Dim colorStrings As String() = {"Red,Green"}For Each colorString As String In colorStringsDim colorValue As ColorsIf [Enum].TryParse(colorString, colorValue) ThenConsole.WriteLine(colorValue)End IfNextEnd Sub End Class"Red"+"Green"=3,因此最終輸出的是Blue,因?yàn)锽lue=3。
轉(zhuǎn)載于:https://www.cnblogs.com/ServiceboyNew/archive/2012/07/17/2595229.html
總結(jié)
以上是生活随笔為你收集整理的“多态枚举”数值如何判断?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android version and
- 下一篇: splunk 实例