目錄
- 列舉
- 位運算
一、列舉
列舉型別是名稱與值的組合。
列舉型別是值型別。
1、為什麼列舉型別是名稱與值得組合?有時我只看到鍵名稱,沒有看到相對的值。
public enum Options { Insert, Update, Save, Delete, Query }
編譯器會給上面補充完整
public enum Options { Insert=0, Update=1, Save=2, Delete=3, Query=4 }
預設從0開始,依次賦值。
2、為什麼列舉型別是值型別
因為System.Enum派生於System.ValueType,而System.ValueType直接派生自System.Object
編譯器遇到列舉型別時,會有自己的理解:
internal struct Options:System.Enum { public const Options Insert = (Options)0; public const Options Update = (Options)1; public const Options Save = (Options)2; public const Options Delete = (Options)3; public const Options Query = (Options)4; public int value__; }
雖然Enum型別不能繼承,但是可以看出編譯器對待列舉型別所形成自己的理解,讓我們明白其原理。
3、操作列舉型別
(1) GetUnderLyingType:返回容納一個列舉型別的值的基礎型別
每個列舉型別都有一個基礎型別,預設是int.所以上面編譯器預設為我們填充int型別的值0~4。
當然這個基礎型別也可以自己指定,可以為byte\sbyte\short\usshot\int\uintr\long\ulong
public enum Options:byte { Insert, Update, Save, Delete, Query }
var type= Enum.GetUnderlyingType(typeof(Options)); string strs = type.ToString();
列舉型別是基元型別,我們可以對其例項進行許多平時的操作符操作,而每個列舉例項,對應著value__欄位。
(2)GetValues:獲取一個陣列,該陣列的每個元素都包含鈣元素的名稱和對應的值。
System.Collections.Generic.Dictionary<int,string> opsDic=new System.Collections.Generic.Dictionary<int,string>(); Options[] ops = (Options[])Enum.GetValues(typeof(Options)); foreach (var o in ops) { try { opsDic.Add((int)o, o.ToString()); } catch (Exception ex) { Console.WriteLine("鍵值{0}已存在", (int)o); } }
(3)GetNames:返回一組字串名稱陣列。
string[] opsNames = Enum.GetNames(typeof(Options));
(4)Parse和TryParse:可以將數值和名稱的字串轉換成對應的列舉型別。
Options turnOption = (Options)Enum.Parse(typeof(Options), "Insert"); Options turnOption1 = (Options)Enum.Parse(typeof(Options), "1");
Options tryTurnOption; Enum.TryParse<Options>("insert", false, out tryTurnOption);
二、位標誌
我們可能需要多個列舉的組合來滿足我們的需要。
位運算是針對二進位制位進行的運算,常用的位運算主要有與(&), 或(|)和非(~)
e.m:1 & 0 = 0, 1 | 0 = 1, ~1 = 0
要使列舉型別具有位運算的能力,需要加上特性[FlagsAttribute]簡寫[Flags]。有些位處於on狀態,有些處於off狀態。所以通常在定義一個None=0的列舉符號。相對應的值都為2的指數倍。為的是後續的運算。
[Flags] public enum Options { None=0, Insert = 1, //二進位制: 0001 Update = 2, //二進位制: 0010 Save = 4, //二進位制: 0100 Delete = 8, //二進位制: 1000 Query = 16 //二進位制:10000 }
許可權列表:
Options hasOps = Options.Insert | Options.Update; string ops = hasOps.ToString();
我們看到, Options.Insert | Options.Update=0001|0010,“|”與操作:1 | 0 = 1,是二進位制位的運算。我們可以得到結果為:0011。對於這個結果怎麼去應用。
許可權判斷:
if ((hasOps & Options.Insert) == Options.Insert) { Console.WriteLine("Has {0}", Options.Insert); }
我們可以根據“&”與操作進行許可權判斷,可以表示為:0011&0001=0001,後面0001==0001,符合條件,有Insert許可權。
例項:專案中,有時會進行正則匹配。
string[] imgsArr = Regex.Split(imgsArea, ",", RegexOptions.IgnoreCase | RegexOptions.Multiline); 這句話主要看後面:RegexOptions.IgnoreCase | RegexOptions.Multiline,可以表示為:0001|0010=0011,意思也就是需要同時符合兩個條件,
:RegexOptions.IgnoreCase不區分大小寫匹配 和 RegexOptions.Multiline 多行模式匹配
[Flags]
public enum RegexOptions { None = 0, IgnoreCase = 1, Multiline = 2, ExplicitCapture = 4, Compiled = 8, Singleline = 16, IgnorePatternWhitespace = 32, RightToLeft = 64, ECMAScript = 256, CultureInvariant = 512, }