可空布尔作为 C# 中的三态变量

Posted

技术标签:

【中文标题】可空布尔作为 C# 中的三态变量【英文标题】:Nullable bool as tri-state variable in C# 【发布时间】:2011-07-16 11:36:10 【问题描述】:

使用可为空的布尔值存储三态值有什么好处吗?例如,null == 1st state, false == 2nd state, true == 3rd state?

开销可能比使用字节枚举要高,但我很好奇。

【问题讨论】:

在看到false == 1 的那一刻,我有点死了(没关系,问题已被编辑) 我觉得这样使用可以为空的 bool 是完全不舒服的,想想一段代码负责检查它的值并将它与枚举或常规整数进行比较 这三个状态分别代表什么? bool?enum 有什么影响? @BoltClock,经过编辑以延长全世界程序员的预期寿命:) @k3b:可以为空的布尔类型bool?Nullable<bool> 的别名。 【参考方案1】:

您应该得到一份Framework Design Guidelines 的副本。

第 177 页有一章在枚举和布尔参数之间选择

其中一个要点是:

请勿使用布尔值,除非您绝对确定永远不需要两个以上的值。

【讨论】:

【参考方案2】:

这是一个有点主观的问题,但我会拒绝,因为它会影响可读性。

【讨论】:

没错。它掩盖了价值背后的实际概念。【参考方案3】:

在 bool 类型的末尾使用 ? 标记,这是一个包含可为空的 bool 的结构。

bool? mytristatebool = null;

【讨论】:

C# 指南:docs.microsoft.com/en-us/dotnet/csharp/language-reference/… 这非常适合我正在做的事情。感谢您的建议,我完全忘记了这一点。 gist.github.com/instance-id/ab406a366238a7088978368daf0c87d6【参考方案4】:

我建议您选择 Enum,因为您现在已经掌握了 3 个状态,并且随着范围蔓延,它可能会进一步增加。因此,Enum 将是一个安全的赌注,并且更准确/更易读,用于描述三种状态,最重要的是第三种状态,它既不是真也不是假。

最后,它更像是为眼睛编码,他们会稍后查看此代码并使其对他们有意义和可读

【讨论】:

【参考方案5】:

我认为这样做是错误的。

布尔值是一种“双态”类型。这是它的定义。

在 C#、C++、Java 或其他语言中。

如果你想模拟三种状态,只需要实现一个枚举,而不是重新发明一个方轮!

【讨论】:

SQL有什么实现?如果有点,可以是0或1。 @Matías:在 SQL 中,表达式 a < b 的计算结果为 TRUEFALSENULL “NULL”是什么情况? @Matías:我不确定你的意思。如果a1 并且bNULL,则表达式的计算结果为NULL。无论如何,由于这是一个 C# 问题,我主要是在开玩笑。 好的,这就是重点。 NULL 不是布尔值。布尔值是“真”或“假”,即使如果你想做“a NULL AND a > b”。【参考方案6】:

如果它是一个 WinForms 程序,那么一种可能性是使用 System.Windows.Forms.CheckState。它具有 Checked、Indeterminate 和 Unchecked 的值 - 这可能适合也可能不适合您的目的。

【讨论】:

【参考方案7】:

更简单的解决方法是使用两个布尔变量。 一个人会保持 null/not-null 另一个将保持真/假

一个应用

当您在布尔属性中缓存计算时,您需要知道它是否已经设置。

例如

// actual variable having true/false
private bool isX = false;
// variable holding wither above is set/not-set i.e. null/not-null
private bool isXSet = false;

public bool IsX

   get
   
      if (isXSet)
      
         return isX;
      
      else
      
         isX = GetX(); // this could be time consuming.
         isXSet = true;
         return isX;
      
   

当上面的 GetX() 耗时且 IsX 被多次访问时,这在性能调整中非常有用。

【讨论】:

【参考方案8】:

对于未知或尚未确定,我会坚持 null。您也失去了对值进行数学运算的可能性。总而言之,我认为不是一个好主意

【讨论】:

【参考方案9】:

这取决于。非常适合像“Has Dog”这样的属性:真假,或者我们只是不知道。

【讨论】:

经验告诉我宁愿有一个枚举:HasDog、NoDog、未指定。 NULL 始终是一个问号。我们是否缺少数据,或者他们是否填写了未指定?并且不可避免地需要Has2DogsHasCat 是的,但 OP 的问题是关于三态,而不是四态等。 你是 OP :-)【参考方案10】:

我明白为什么人们建议不要使用它来表示选项 A、B 和 C。我也会为此使用枚举。

但是布尔值?非常适合表示可能尚未获取或生成的实际布尔值。不,有一个单独的 bool 来获取并不简单,它更混乱。恕我直言

现在如果只有 C# 允许使用局部静态变量,那么我们就可以让它完全自包含,就像这样:

bool isSomething
    get
        static bool? _isSomething = null;
        if (null == _isSomething)
            _isSomething = goFetchIsSomething();
        
        return _isSomething == true;
     

但是由于纯粹主义者讨厌可读的代码,你能做的最好的就是这个

private bool? _isSomething = null; //Pretty please don't try to use me outside of isSomething
bool isSomething
    get
         if (null == this._isSomething)
             this._isSomething = goFetchIsSomething();
         
         return this._isSomething == true;
    

【讨论】:

以上是关于可空布尔作为 C# 中的三态变量的主要内容,如果未能解决你的问题,请参考以下文章

Java 中的三态复选框

进程的三态模型

WPF中 三态图 用啥控件呢?

在C#中,如何将键盘的空输入转换为可空类型的布尔变量?

进程线程进程池进程三态同步异步并发并行串行

Linux中的进程 --fork,exec,守护进程分析