【问题标题】:Flags attribute vs HashSet标志属性与 HashSet
【发布时间】:2015-07-16 09:49:41
【问题描述】:

我注意到较新版本的 C# 允许使用 [flags] 属性调整 enum 构造以表示一组按位标志。

在我看来,C# 已经有一个非常好的结构,称为 HashSet 来表示一个集合,并且我经常在我的代码中使用枚举的 Hashset。除了处理效率之外,是否还有其他示例,其中标志枚举提供了使用普通集合无法完成的功能?

恕我直言,传统枚举在语义上与一组标志如此不同,使用属性将一个属性转换为另一个似乎是完全的混蛋。

【问题讨论】:

  • Flags 从一开始就存在,没有语义价值。它拥有的唯一功能是改变ToString 的行为方式。您仍然需要提供正确的值。
  • 一些重构和代码分析工具也注意到了它的存在。
  • 我不知道您所说的“传统枚举”是什么意思,但我记得 30 年前在 C 代码中工作时使用了那些“混蛋”枚举。据我所知,只要 enum 出现在 C 语言中,使用枚举来保存标志值的技术就已经存在了。

标签: c# data-structures enums set


【解决方案1】:

例如属性

  // MyAttribute can be applied to constructors, events and methods only
  [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Event | AttributeTargets.Method)]
  public class MyAttribute {
    ... 
  }

你不能使用HashSet<T>

  AttributeTargets.Constructor | AttributeTargets.Event | AttributeTargets.Method

在上下文中;唯一(可读)的可能性是带有[Flags] 选项的AttributeTargets 枚举

【讨论】:

  • 尽管您可以创建一个包含这 3 个值的哈希集。 flags 枚举是属性的好选择的原因是属性需要常量参数,而 hashet 不需要。
【解决方案2】:

我注意到较新版本的 C# 允许通过使用 [flags] 属性调整 enum 构造以表示一组按位标志。

我很确定它存在于 .NET 1.0 中。它肯定在 .NET 1.1 中。标志技术从 .NET 上最早的实验工作就已经存在,因为它是使用整数的二进制表示所固有的,无论一种语言是否提供了一种工具来帮助反映这一点。

在我看来,C# 已经有一个非常好的构造,称为 HashSet 来表示一个集合。

从 .NET 3.5 开始就有了。在 2.0 之前,.NET 甚至没有泛型。

恕我直言,传统枚举在语义上与一组标志非常不同,

传统上,枚举用于二进制标志已经很长时间了。这有助于强制使用整数值作为二进制标志的类型,这是计算机科学早期使用的一种技术。一个典型的例子是 unix 文件系统的权限标志,其中一个数字由代表不同类别用户的读、写和执行权限的位组成。

我经常在我的代码中使用枚举的哈希集

如果这些枚举代表标志值,坦率地说这很奇怪。除此之外,您不能拥有const HashSet。这听起来像是过早悲观的极端情况。

【讨论】:

  • @JimMischel 过早的悲观主义在人们认为自己有一个聪明的变种时会出现很多,但最终发现只是让代码变得更慢、更大、更容易出错并且更难维护已经发现任何需要更慢、更大、更容易出错和更难维护的需求。
  • 哦,效果我熟悉了;我什至可能自己做过一两次。只是以前没听说过它叫“过早悲观”。
  • @JimMischel 是的,正是意识到自己已经完成了这件事,才产生了幽默的效果。当我第一次使用它时,我认为它是我自己的造币,但显然其他人首先想出了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 2016-07-19
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多