标志枚举与常规枚举的HashSet

Hei*_*nzi 6 .net c# enums coding-style

是否有令人信服的理由在常规枚举的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
}
Run Code Online (Sandbox Code Playgroud)

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

我错过了Flags选项的一些优点,并证明它在"常规"代码中的使用是正确的吗?

Kon*_*lph 7

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

除了它们的数量级更高效之外呢?这可能与您无关,但它是如此明显的优化,它通常是有道理的.

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

  • 我想我应该介入并在这里捍卫我的同事:他们是伟大的开发人员,但是他们已经在VBA和.NET中开发了LOB应用程序多年而不需要位操作,因此理解`a&= ~b`肯定需要比`a.Remove(b)`. (5认同)
  • @Heinzi不幸的是我不认为这是可辩护的.它只是一项必不可少的技能,就像使用刀作为厨师一样,即使你有一个搅拌机. (4认同)