“无条件运营商短路”是什么意思?

给未来访客的提示:这个问题是基于错误的repro代码。 这个?. 操作员确实发生短路。 您现在可以关闭此浏览器选项卡。


网络上有很多来源声称空条件运算符( ?. )短路(例如http://www.informit.com/articles/article.aspx?p=2421572,搜索“电路”)。 我无法检测到任何这样的事情:

    static void Main()
    {
        var c = new C();

        Console.WriteLine(c?.Inner?.Inner); //does not rely on short circuiting, works
        Console.WriteLine(c?.Inner.Inner); //throws NullReferenceException
    }

    class C
    {
        public C Inner;
    }

在这里,第一行是因为第二行?. 。 第二个?. 将null看作其第一个操作数,因此也返回null。 这不是短路。

显然,即使空情况被触发,链的其余部分也会执行。 链不中止。 对我而言,短路意味着链条中止。 MSDN声称是这种情况,但代码示例不显示短路:

//The last example demonstrates that the null-condition operators are short-circuiting
int? count = customers?[0]?.Orders?.Count();
// null if customers, the first customer, or Orders is null

这种行为在C#6开发周期中是否曾经发生过变化? 这将解释网络上的不良来源。 如果不在那里,为什么会有太多关于短路的说法? 我可能在这里误解了一些东西。

这不是重复的,因为它与运营商是否短路有关(答案:否,尽管接受的答案没有这样说)。 这个候选人是关于可空的布尔和其他无关的。


它确实发生短路(如果我们的意思是“终止呼叫链”)。

考虑这个代码:

using System;

namespace ConsoleApplication1
{
    class C
    {
        public C Inner
        {
            get
            {
                Console.WriteLine("Inner called.");
                return this; // Change this to `return null;`
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var c = new C();

            var x = c?.Inner?.Inner?.Inner;
        }
    }
}

运行它,它会打印

Inner called.
Inner called.
Inner called.

现在改变return this; return null; ,它会打印

Inner called.

从而表明呼叫链在第一个空值处停止。

现在将表达式更改为:

var x = c?.Inner?.Inner.Inner;

它仍然会打印

Inner called.

因为它正在短路。

显然,它必须至少访问一次Inner以查看它是否为null。 如果c本身为空,那么根本不访问Inner

请注意,给出的表达式:

var x = c?.Inner.Inner;

它会在第一次使用.Inner时给出一个空引用异常,因为它已经使用c?检查了c不为空c? 现在它继续使用.Inner

如果c为null,那么它将不会继续访问.Inner因为c?.


这里的短路意味着当你有例如obj?.Property1?.Property2?.Property3objnull ,整个表达式将返回null,并且不会调用其他属性(因为它们将抛出)。

这种短路可能发生在每个人身上?. 取决于哪一部分是null 。 如果obj不为null,并且第一个Property只有另外两个不会被调用。 第二个也是如此。

短语表达的表达式 ,而不是表达式后面的其他语句。


简而言之,短路是一种保证,如果它确定一个属性为空,则不会继续尝试评估其余属性。

通过一个不涉及空操作符的示例可能会更清楚。

在下面的例子中,我们检查x是否为空,然后检查其属性的值。

if(x != null & x.SomeProperty == 1)

但是,如果x为空,这仍然会抛出异常,因为它要评估两个条件。 即使x为null,它仍然会尝试检查x.SomeProperty并且它将抛出NullReferenceException

但是,如果我们使用&&运算符

if(x != null && x.SomeProperty == 1)

然后它“短路”。 如果第一个条件不成立,那么它甚至不会评估第二个条件。 这是检查,看看他们是否都是真实的。 但如果第一个不是真的,那么它们都不可能是真的 - 第二个的价值并不重要。 所以它在第一个条件之后停止。

短路最终意味着,如果它评估任何导致其余条件不相关的事情,则保证不评估其余条件。

链接地址: http://www.djcxy.com/p/75163.html

上一篇: What is meant by "the null conditional operator short circuits"?

下一篇: How to make multiplication operator (*) behave as short