【问题标题】:Nullable bool as tri-state variable in C#可空布尔作为 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> 的别名。

标签: c# state boolean


【解决方案1】:

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

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

其中一个要点是:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

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

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

    bool? mytristatebool = null;
    

    【讨论】:

    【解决方案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;
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-09-02
              • 1970-01-01
              • 1970-01-01
              • 2018-06-08
              • 1970-01-01
              • 2012-12-06
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多