.NET的内置标志枚举操作非常有限。大多数时候,用户都只需要弄清按位运算逻辑。
在.NET 4中,HasFlag
添加了Enum
该方法以帮助简化用户代码,但不幸的是它存在许多问题。
HasFlag
不是类型安全的,因为它接受任何类型的枚举值参数,而不仅仅是给定的枚举类型。
HasFlag
关于是否检查该值是否具有枚举值参数提供的所有标志或任何标志,模棱两可。顺便说一句。
HasFlag
速度很慢,因为它需要装箱,这会导致分配并因此导致更多垃圾回收。
由于.NET对标志枚举的支持有限,我编写了OSS库Enums.NET,该库解决了每个问题,并使标志枚举的处理变得更加容易。
下面是仅使用.NET框架提供的一些操作以及它们的等效实现。
组合标志
。净 flags | otherFlags
枚举 flags.CombineFlags(otherFlags)
删除标志
。净 flags & ~otherFlags
枚举 flags.RemoveFlags(otherFlags)
常见标志
。净 flags & otherFlags
枚举 flags.CommonFlags(otherFlags)
切换标志
。净 flags ^ otherFlags
枚举 flags.ToggleFlags(otherFlags)
有所有标志
.NET (flags & otherFlags) == otherFlags
或flags.HasFlag(otherFlags)
枚举 flags.HasAllFlags(otherFlags)
有任何标志
。净 (flags & otherFlags) != 0
枚举 flags.HasAnyFlags(otherFlags)
获取标志
。净
Enumerable.Range(0, 64)
.Where(bit => ((flags.GetTypeCode() == TypeCode.UInt64 ? (long)(ulong)flags : Convert.ToInt64(flags)) & (1L << bit)) != 0)
.Select(bit => Enum.ToObject(flags.GetType(), 1L << bit))`
枚举 flags.GetFlags()
我正在尝试将这些改进合并到.NET Core中,也许最终合并到完整的.NET Framework中。你可以在这里查看我的建议。