Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 标志枚举与常规枚举的哈希集_C#_.net_Coding Style_Enums - Fatal编程技术网

C# 标志枚举与常规枚举的哈希集

C# 标志枚举与常规枚举的哈希集,c#,.net,coding-style,enums,C#,.net,Coding Style,Enums,在常规枚举的哈希集上使用标志枚举(即位掩码)是否有令人信服的理由?据我所知,两者都解决了相同的问题: 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,

在常规枚举的哈希集上使用标志枚举(即位掩码)是否有令人信服的理由?据我所知,两者都解决了相同的问题:

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
}
enum颜色{红、绿、蓝}
[标志()]
枚举颜色{无=0,红色=1,绿色=2,蓝色=4}
无效测试()
{
//初始化
var supportedColors1=新哈希集{Color.Red,Color.Green};
var supportedColors2=Colors.Red | Colors.Green;
//比较
if(supportedColors1.Contains(Color.Green)){/*…*/}
如果((supportedColors2&Colors.Green)!=0){/*…*/}
//操纵
支持的颜色1.移除(颜色为红色);
supportedColors2^=Colors.Red;//如果我确定包含红色
supportedColors2&=~Colors.Red;//如果我不确定
}
这可能是一个品味问题,但对于没有硬件或系统级位翻转背景的人(=我的同事),我认为Set选项更具可读性。当需要进行微优化(更好的性能、更少的内存)或P/调用Windows API时,我可以看到Flags选项的优势,但对于标准业务线数据库应用程序,我倾向于选择Set选项以提高可读性

Flags选项是否有一些我没有注意到的优点,可以在“常规”代码中使用

标志选项是否有一些我错过的优点

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


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

除了效率问题外,
HashSet
解决方案可能还不错。但是我认为开发人员应该尽可能更好地编写正确的代码,而不是尽可能地(被其他同事)接受……如果有人没有足够的技能来理解您的清晰和正确的解决方案,您无需为此付费。

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

我想我应该站出来为我的同事辩护:他们是优秀的开发人员,但他们多年来一直在VBA和.NET中开发LOB应用程序,而不需要位操作,因此理解
a&=~b
肯定比
a.Remove(b)
@Heinzi需要更长的时间。不幸的是,我认为这是站不住脚的。这只是一项基本技能,就像用刀子做饭一样,即使你有搅拌器。我认为你关于数据库存储的评论是不对的。你能详细说明一下吗?其余的也很脆弱。实现扩展方法非常简单和快速,您只需执行一次。之后将不会有“可读性较差的代码”——这与使用哈希集是一样的。您好,是的,问题是关于数据库驱动的应用程序,因此假设我们从数据库中获取数据集,并且需要将其存储在某个位置,然后对其进行排序/过滤,我认为这是最快的(也是最常见的做法)解决方案是使用某种类型的泛型集合。结果是一样的,性能将是一样的(hashset执行得很好),并且您将不需要自己实现hashset支持的所有扩展方法。当然,如果没有明显的好处,那么重用已经实现的东西比自己重写要快。另一点是大多数开发人员(如果您在团队中工作)都熟悉列表及其方法,而不是枚举标志。