传统方法是在上使用
Flags属性
enum:
[Flags]public enum Names{ None = 0, Susan = 1, Bob = 2, Karen = 4}然后,您将按照以下方式检查特定名称:
Names names = Names.Susan | Names.Bob;// evaluates to truebool susanIsIncluded = (names & Names.Susan) != Names.None;// evaluates to falsebool karenIsIncluded = (names & Names.Karen) != Names.None;
逻辑按位组合可能很难记住,因此我可以通过一
FlagsHelper堂课* 使自己的生活更轻松:
// The casts to object in the below pre are an unfortunate necessity due to// C#'s restriction against a where T : Enum constraint. (There are ways around// this, but they're outside the scope of this simple illustration.)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 4.0中已经存在上述方法的等效项:
Enum.HasFlag。不过,
Set和
Unset方法似乎没有等效项。所以我仍然会说这堂课有一些优点。
注意:使用枚举只是解决此问题的 常规 方法。您可以完全翻译上面的所有代码以改为使用int,它也将正常工作。



