The usage of the enumeration type flag [Flags] feature and the method for adding enumeration types, flags Enumeration
Suppose there is a code segment like this. You need to determine which weapons the role is equipped with, and then perform other operations based on this attribute of the role. In this case, we can use enumeration to mark the weapons that a role can equip.
Public enum Equipment {Knife, gun, Arrow, bow} public sealed class Player {internal Equipment equipmentState; // used to describe what weapons the role can use //...... other members}
This is a problem. When a role can be equipped with multiple weapons, is it necessary to use multiple variables to indicate the weapons he can use? Or add new members, knives and arrows, knives and arrows, and bows to the Equipment type ...... this is because equipmentState in Player can only represent one State, but not multiple States.
That is, its value can only be one of the knives, guns, arrows, and bows.
In this case, the Flags feature can be used to modify the Equipment type. It enables equipmentState to be represented in multiple States. Now equipmentState is equivalent to a set.
1 namespace UsageOfFlagsAttribute 2 {3 [Flags] 4 public enum Equipment 5 {6 NONE = 0x0000, 7 knives = 0x0001, 8 guns = 0x0002, 9 arrow = 0x0004,10 bow = 0x000811} 12 13 public sealed class Player14 {15 internal Equipment equipmentState; // describes the weapons that a role can use. 16} 17 18 19 class Program20 {21 static void Main (string [] args) 22 {23 Player player = new Player (); 24 player. equipmentState = Equipment. knife | Equipment. bow; // a set that can be expressed as multiple States 25} 26} 27}
After Flags are used, it can be calculated by bit. Generally, there are three types of enumeration calculation by bit.
By bit or ("|"): add the specified symbol to the enumeration instance.
Bitwise AND ("&"): determines whether a specified symbol exists in the enumeration instance.
XOR ("^"): deletes the symbol specified in the enumeration instance.
Class Program {static void Main (string [] args) {Player player = new Player (); // By bit or player. equipmentState = Equipment. knife; player. equipmentState = player. equipmentState | Equipment. bow; Console. writeLine (player. equipmentState. toString (); // print the result: knife, bow // bitwise AND player. equipmentState = Equipment. knife | Equipment. bow; player. equipmentState = player. equipmentState & Equipment. knife; Console. writeLine (player. equipmentState. toString (); // print the result: knife // exclusive or player. equipmentState = Equipment. knife | Equipment. bow; player. equipmentState = player. equipmentState ^ Equipment. bow; Console. writeLine (player. equipmentState. toString (); // print the result: knife Console. readKey ();}}
However, every time you write player. equipmentState = player. equipmentState ^ Equipment.; the value assignment code is not readable and time-consuming. Therefore, you can extend the method to encapsulate these operations.
1 public static class EnumExtendMethods 2 {3 /// <summary> 4 // determine whether the specified symbol 5 exists in the Peugeot enumeration instance. /// </summary> 6 // /<param name = "eqipment"> instance </param> 7 // <param name = "checkState"> specified symbol </param> 8 // <returns> </returns> 9 public static bool Contains (this Equipment equipment, equipment checkState) 10 {11 if (checkState = 0) 12 {13 throw new ArgumentOutOfRangeException ("checkState", "cannot be NONE"); 14} 15 return (equipment & checkState) = checkState; 16} 17 18 /// <summary> 19 // remove the specified symbol from the enumeration instance 20 /// </summary> 21 // <param name =" equipment "> </param> 22 // <param name =" removeState "> specify the symbol to be removed </param> 23 // <returns> </returns> 24 public static Equipment Remove (this Equipment equipment, equipment removeState) 25 {26 return equipment ^ removeState; 27} 28 29 // <summary> 30 // Add the specified symbol 31 to the enumeration instance /// </summary> 32 // <param name = "equipment "> </param> 33 // <param name =" addState "> </param> 34 // <returns> </returns> 35 public static Equipment Append (this equipment equipment, equipment addState) 36 {37 return equipment | addState; 38} 39}
Now you can call
1 class Program 2 {3 static void Main (string [] args) 4 {5 Player player = new Player (); 6 7 // By bit or 8 player. equipmentState = Equipment. knife; 9 player. equipmentState = player. equipmentState. append (Equipment. bow); 10 Console. writeLine (player. equipmentState. toString (); // print the result: knife, bow 11 12 // by position and 13 player. equipmentState = Equipment. knife | Equipment. bow; 14 if (player. equipmentState. contains (Equipment. knife) 15 {16 Console. writeLine (player. equipmentState. toString (); // print the result: knife, bow 17} 18 19 // different or 20 player. equipmentState = Equipment. knife | Equipment. bow; 21 player. equipmentState = player. equipmentState. remove (Equipment. bow); 22 Console. writeLine (player. equipmentState. toString (); // print the result: knife 23 24 Console. readKey (); 25} 26}