标志枚举与常规枚举的HashSet

时间:2012-01-31 09:55:44

标签: c# .net coding-style enums

是否有令人信服的理由在常规枚举的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选项的一些优点,并证明它在“常规”代码中的使用是正确的吗?

3 个答案:

答案 0 :(得分:7)

  

我错过了Flags选项的一些优点

除了数量级更高效的事实?这可能与您无关,但它通常是有意义的明显优化。

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

答案 1 :(得分:1)

如你所知,你可以同时实现两者。如果要存储来自数据库的数据,使用HashSet可能是更好的选择,在性能方面不会有任何明显的差异。 当然,您最终会得到一个更加可用(和可读)的代码,并且具有与您要整理的数据“更适合”的类型。在这两种情况下,您将迭代或检查容器中是否存在值。虽然Hashset带有典型的列表(包含等等)的所有扩展,但是你必须自己实现这些功能(例如使用自定义扩展方法)。结果将是开发速度减慢和代码不太可读(对于您的同事:)没有任何改进。 Here's a good overview about Enum flags

答案 2 :(得分:0)

除了效率问题,HashSet解决方案可能正常。但我认为开发人员应该尽可能地更好地编写正确的代码,而不是像其他同事那样可以接受......如果有人不够熟练,无法理解你的清晰正确的解决方案,你就不需要支付为此。