【问题标题】:If I need a bool to have the option to be set to null as well, am I better off with a nullable bool or a custom enum?如果我需要一个 bool 也可以将选项设置为 null,那么我最好使用可为空的 bool 还是自定义枚举?
【发布时间】:2015-09-04 09:52:00
【问题描述】:

假设我正在检测程序的选项。

如果程序版本号低于某个限制,这些选项可以启用、禁用或不可用。

如果该选项不可用,我需要将其设置为 null。

现在,我有两条路要走。

第一个:

bool? option;

使用可为空的布尔值使我能够将我的选项设置为真、假或空。这会很好用并满足我的要求。

不过,我也可以使用方式二:

enum{
    unavailable,
    enabled,
    disabled
}

或类似的东西。

现在,如果我可以选择,在内存使用、可访问性等方面哪个更好?

我会说可以为空的布尔值更容易使用,但我看到很多人对可空值非常消极,更喜欢枚举方式。

谁能帮我解释一下?

【问题讨论】:

  • 这是一个见仁见智的问题。 TBH 我可能会使用枚举,因为具有 3 个值的布尔值似乎是错误的。此外,由于某些阶段的错误,布尔值可能未设置。枚举还会为增加可能值的数量留出空间,而无需重写应用程序。
  • 最近,很多人对null 的价值观提出了批评。其中大部分是关于null 的未定义语义:null 没有一致或自记录的语义;它可以表示“我不知道”、“我不在乎”、“那不相关”、“发生错误”或其他一百万件事。因此,为了清楚起见,您可能希望避免使用nulls。

标签: c# enums nullable


【解决方案1】:

我投票给枚举:

  • 您可能想要添加一些其他选项,例如“已过时”、“不支持”等。
  • 您可能想要扩展逻辑,例如添加IsOff,如果它是unavailabledisabled 等。

所以

public enum OptionValue {
  Unavailable,
  Enabled,
  Disabled
  // Obsolete,    // can be found in earlier versions only
  // NotSupported // say, technically could be enabled but it will do nothing
  // Proposed // in future versions 
}

// if you add some values into OptionValue enum, 
// you have to update this class only, not the whole application
public static class OptionValueExtensions() {
  // If option is available and enabled 
  public static Boolean IsOn(this OptionValue value) { 
    return value == OptionValue.Enabled;
  }
  // If option is either disabled or unavailable
  public static Boolean IsOff(this OptionValue value) { 
    return (value == OptionValue.Disabled) || (value == OptionValue.Unavailable);
  }
}

...

OptionValue myOption = ...

// it's easy with enum (and extension class)
// if myOption is in fact (by whatever reason) is off then...
if (myOption.IsOff()) {...}

【讨论】:

    【解决方案2】:

    我认为没有正确或错误的答案,但以下是我对此的想法以及从我的角度来看会少一些气味。

    我会倾向于枚举。我认为您可能会有第四个值“NotSet”。

    从我的角度来看,应该将“null”状态评估为语义值,因为您无法区分“unaviable”选项是指意思还是未设置(由于错误)

    【讨论】:

      【解决方案3】:

      “布尔?”在内存中占用 2 个字节。它有一个超出常规布尔值的额外字节开销。

      我们考虑一个三态枚举,它可以用一个字节后备存储来实现。请注意在枚举类型声明之后如何使用分号语法“:字节”。

      可空的布尔值可以表示三个值:空、假和真。但正如我们在这里看到的,使用字节后备存储的自定义枚举类型可以更有效地表示这三个值。在类型安全方面,这些方法同样有效。 然而: 枚举类型避免了将值类型包装在泛型结构中相关的开销。

      More details

      【讨论】:

      • 你能把你所有的文字都放在引号里吗?因为它是从你的链接复制粘贴的?
      • 我建议您明确指出您从链接中引用的内容,否则答案可能会因抄袭而被混淆并被删除
      • 听说bool占用4个字节(存储为int32)所以bool?应该是 8
      • 内存效率不如语义重要。无论如何,.NET 可能会将布尔值打包为优化,如链接文章所示。
      • @vlad sizeof(bool) 返回 1,而不是 4。
      猜你喜欢
      • 2017-11-24
      • 1970-01-01
      • 2010-12-28
      • 1970-01-01
      • 2017-07-20
      • 2017-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多