วิธีดั้งเดิมในการทำเช่นนี้คือการใช้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.HasFlag4.0: SetและUnsetวิธีการไม่ปรากฏว่ามีเทียบเท่าแม้ว่า; ดังนั้นฉันยังคงบอกว่าคลาสนี้ได้บุญ
หมายเหตุ: การใช้ enums เป็นเพียงวิธีการทั่วไปในการแก้ไขปัญหานี้ คุณสามารถแปลโค้ดทั้งหมดข้างต้นเพื่อใช้ ints แทนและมันก็ใช้ได้เช่นกัน