วิธีดั้งเดิมในการทำเช่นนี้คือการใช้Flags
แอตทริบิวต์บนenum
:
[Flags]
public enum Names
{
None = 0,
Susan = 1,
Bob = 2,
Karen = 4
}
จากนั้นคุณจะตรวจสอบชื่อเฉพาะดังต่อไปนี้:
Names names = Names.Susan | Names.Bob;
bool susanIsIncluded = (names & Names.Susan) != Names.None;
bool karenIsIncluded = (names & Names.Karen) != Names.None;
การรวมค่าบิตตามตรรกะอาจเป็นเรื่องยากที่จะจำดังนั้นฉันจึงทำให้ชีวิตง่ายขึ้นด้วยFlagsHelper
คลาส *:
public static class FlagsHelper
{
public static bool IsSet<T>(T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
return (flagsValue & flagValue) != 0;
}
public static void Set<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue | flagValue);
}
public static void Unset<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue & (~flagValue));
}
}
สิ่งนี้จะทำให้ฉันสามารถเขียนโค้ดด้านบนใหม่เป็น:
Names names = Names.Susan | Names.Bob;
bool susanIsIncluded = FlagsHelper.IsSet(names, Names.Susan);
bool karenIsIncluded = FlagsHelper.IsSet(names, Names.Karen);
โปรดทราบว่าฉันสามารถเพิ่มลงKaren
ในชุดได้โดยทำสิ่งนี้:
FlagsHelper.Set(ref names, Names.Karen);
และฉันสามารถลบSusan
ในลักษณะเดียวกัน:
FlagsHelper.Unset(ref names, Names.Susan);
* ณ Porges ชี้เทียบเท่าของIsSet
วิธีการดังกล่าวมีอยู่แล้วใน .NET Enum.HasFlag
4.0: Set
และUnset
วิธีการไม่ปรากฏว่ามีเทียบเท่าแม้ว่า; ดังนั้นฉันยังคงบอกว่าคลาสนี้ได้บุญ
หมายเหตุ: การใช้ enums เป็นเพียงวิธีการทั่วไปในการแก้ไขปัญหานี้ คุณสามารถแปลโค้ดทั้งหมดข้างต้นเพื่อใช้ ints แทนและมันก็ใช้ได้เช่นกัน