标志enum与常规enum的HashSet

本文关键字:enum HashSet 标志 常规 | 更新日期: 2023-09-27 18:21:54

是否有令人信服的理由在正则枚举的HashSet上使用Flags枚举(即位掩码)?据我所知,两者都解决了同一个问题:

enum Color { Red, Green, Blue }
[Flags()]
enum Colors { None = 0, Red = 1, Green = 2, Blue = 4 }
void Test()
{
    // initialization
    var supportedColors1 = new HashSet<Color> { Color.Red, Color.Green };
    var supportedColors2 = Colors.Red | Colors.Green;
    // comparison
    if (supportedColors1.Contains(Color.Green)) { /* ... */ }
    if ((supportedColors2 & Colors.Green) != 0) { /* ... */ }
    // manipulation
    supportedColors1.Remove(Color.Red);
    supportedColors2 ^= Colors.Red;  // if I'm sure that Red is contained
    supportedColors2 &= ~Colors.Red; // if I'm not sure
}

这可能是一个品味问题,但对于没有硬件或系统级比特翻转背景的人(=我的同事)来说,我认为Set选项更可读。当需要微优化(更好的性能,更少的内存)或P/调用Windows API时,我可以看到Flags选项的优势,但对于标准的业务线数据库应用程序,为了可读性,我很想选择Set选项。

我是否遗漏了Flags选项的一些优点,并证明它在"常规"代码中的使用是合理的?

标志enum与常规enum的HashSet

我错过的Flags选项有什么优点吗

除了它们的效率是数量级之外?这可能与您无关,但这是一个明显的优化,通常是有意义的。

此外,如果您不喜欢位操作语法(我不怪您),请尝试定义扩展方法来封装它们。但我认为任何有能力的程序员,无论他们的背景如何,都绝对需要知道常见的位操作。如果你的同事被这种用法难住了,你就有大问题了。

HashSet解决方案可能工作良好,但效率问题除外。但我认为开发人员应该尽可能地写出正确的代码,而不是尽可能地被其他同事接受。。。如果有人不够熟练,无法理解你清晰正确的解决方案,你就不必为此付出代价。

正如您所知,您可以使用这两种方法实现相同的效果。如果你想存储来自数据库的数据,使用HashSet可能是一个更好的选择,在性能方面不会有任何明显的差异。毫无疑问,您最终会得到一个更可用(可读)的代码,以及一个更适合您想要排序的数据的类型。在这两种情况下,您都将迭代或检查容器中是否存在值。虽然Hashset附带了列表(contains等)的所有典型扩展,但您必须自己实现这些功能(例如使用自定义扩展方法)。结果将是开发速度减慢,代码可读性降低(对于您的同事来说:),而没有任何改进。以下是关于枚举标志

的一个很好的概述