【问题标题】:Null-coalescing operator and operator && in C#C# 中的空合并运算符和运算符 &&
【发布时间】:2011-02-13 02:41:01
【问题描述】:

在下一种情况下是否可以以任何方式一起使用运算符??和运算符&&

bool? Any
{
   get
   {
      var any = this.ViewState["any"] as bool?;
      return any.HasValue ? any.Value && this.SomeBool : any;
   }
}

这意味着下一步:

  • 如果any 为空,则this.Any.HasValue 返回false
  • 如果any 有值,则返回值考虑另一个布尔属性,即Any && SomeBool

【问题讨论】:

  • 为什么要使用 ??操作员?让它更短?
  • @Henk Holterman:是的。并供运营商使用实践。

标签: c# boolean-logic logical-operators null-coalescing-operator


【解决方案1】:

我想知道为什么到目前为止没有人提出这个建议:

bool? any = this.ViewState["any"] as bool?;
return any & this.SomeBool;

返回

  • null如果any为null,不管this.SomeBool的值是多少;
  • true 如果anythis.SomeBool 都为真;和
  • false 如果any 不为空,并且this.SomeBool 为假。

【讨论】:

  • 代码看起来不错,但描述是错误的(你怎么能同时返回 nullfalse,但这就是你的规则所说的 any == nullthis.SomeBool == false .
  • @Henk Holterman:为什么操作数是'bool' and 'bool?' 而不是'bool?' and 'bool'!?左边的操作数显然是 bool? 类型,因为我声明它是这样的。
  • @Henk Holterman:是的,但是我在将其复制到我的答案时打错了 :-( 现在已修复。我的测试程序:bool? x = null; bool y = true; bool? z = x & y;
  • 你的代码可以改写为:return this.ViewState["any"] as bool? & this.SomeBool;,对吧?
  • 一个重要的警告:&& 是一个短路布尔求值,但按位求值器& 不会短路。因此,在上面, this.SomeBool 无论如何都会被评估。因此请注意,在使用 Nullable<bool> 时,这并不能完全替代 && 的典型用法。
【解决方案2】:

Null Coalescing 运算符不适用于您为方法构建逻辑的方式。当然你可以把它强行放进去,但它会看起来很丑,而且只会让阅读它的人感到困惑。

我发现原始代码难以阅读和理解,因此重构并删除了三元运算符以揭示意图。

bool? any = this.ViewState["any"] as bool?;

if (any == null)
    return null;

return any.Value && this.SomeBool;

Null 合并只是很好的简写,应该谨慎使用

Person contact = Mother ?? Father ?? FirstSibling;

比以下更能表达意图,更容易阅读和维护:

Person contact = Mother;
if (contact == null)
    contact = Father;
if (contact == null)
    contact = FirstSibling;

【讨论】:

    【解决方案3】:

    问题是,你真的不想使用 ??操作员。它的目的是让避免空值变得容易,你实际上想要保留空值。

    【讨论】:

      【解决方案4】:

      我认为你想要做的是:

      return any ?? (any.Value && this.SomeBool) ? true : new Nullable<bool>();
      

      但是,我认为在这种情况下,使用 if 块可能更清楚:

      if ( !any.HasValue )
        return (any.Value && this.SomeBool) ? true : any;
      else 
        return any;
      

      如果有null,那么你要返回truenull,对吧?

      【讨论】:

        【解决方案5】:

        这是你的意思吗?

        bool? Any 
        { 
           get 
           { 
              return ((this.ViewState["any"] as bool?) ?? false) && this.SomeBool;
           } 
        } 
        

        我将返回值保留为 bool?但看起来它可以改为 bool。

        这是这样测试的:

        class Program
        {
            private static readonly Dictionary<string, object> ViewState = new Dictionary<string, object>();
            private static bool SomeBool;
        
            static void Main(string[] args)
            {
                ViewState["any"] = (bool?)null; SomeBool = true; Console.WriteLine(Any);
                ViewState["any"] = (bool?)false; SomeBool = true; Console.WriteLine(Any);
                ViewState["any"] = (bool?)true; SomeBool = true; Console.WriteLine(Any);
                ViewState["any"] = (bool?)null; SomeBool = false; Console.WriteLine(Any);
                ViewState["any"] = (bool?)false; SomeBool = false; Console.WriteLine(Any);
                ViewState["any"] = (bool?)true; SomeBool = false; Console.WriteLine(Any);
                Console.ReadLine();
            }
        
            static bool? Any
            {
                get
                {
                    return ((ViewState["any"] as bool?) ?? false) && SomeBool;
                }
            }
        }
        

        返回

        False
        False
        True
        False
        False
        False
        

        这里的行为与原始行为不太一样,因为如果测试用例 1 和 4 相同,则应返回 null。但也许这种行为不是必需的?

        【讨论】:

        • 不幸的是,没有。 result as bool? 一直是 HasValue = true。不是吗?
        • 如果任何一个为空且其他两个条件为假,他想返回空。所以,他想要 TRUE、FALSE 和 NULL
        • 丹尼尔,非常感谢您的详细解答!但不幸的是,我们讨论了不同的行为——我需要保持返回值为Nullable&lt;bool&gt;,所以检查HasValue 会有意义
        • 我理解并且在这种情况下我同意 Henk 的观点,即没有任何方法可以使用 ??和 && 在保持这种行为的同时使其更短/更清晰。
        【解决方案6】:

        既然你想在源是null的情况下返回null,我认为??不会帮助你写得更短或更清晰。

        【讨论】:

        • 看来你是对的。运算符?? 用于在任何情况下返回一个值。这正是我不需要的..
        【解决方案7】:

        这有你描述的行为:

        return (any ?? false) &amp;&amp; this.SomeBool

        【讨论】:

        • 正如 Daniel Renshaw 的回答,你的也总是有价值 - truefalse,绝不是 null
        最近更新 更多