通过短路评估跳过条件的前/后增量

时间:2013-06-18 20:49:29

标签: c# compilation

所以,如果我有一个表达式:

if (obj != null && i++ % divisor == 0)
{
....
}

objnull,然后i永不递增。如果我使用

i++; 
if (obj != null && i % divisor == 0)
{
....
}

然后,当然,i会增加。

这是设计的吗?我从优化的角度理解短路评估,但我(错误地)假设编译器会识别后增量表达式并对其进行评估。

(如果这是在规范中,我找不到它 - 只是在这里寻找一些(喘气)意见。)

更新

这是实际的代码。

    private int _frameNumber = 0;

    private void simulator_OnFrameEnd(object sender, System.EventArgs e)
    {
        _frameNumber++; 

        if (_visualizer != null && _frameNumber % _config.VisualizerUpdateFrequency == 0)
        {
            var field = _simulator.GetField(_config.PreviewField);

            _visualizer.Update(field, _simulator.FrameTime);
        }

        if (_frameNumber % _config.OptimizerRegridFrequency == 0)
        {
            _simulator.UpdateFieldGrids();

        }

    }

5 个答案:

答案 0 :(得分:6)

后增量仅是对陈述的后评估。由于该语句从未被评估(它被短路),所以它被跳过了。

更直观的方式是将if语句想象为嵌套:

if (obj != null)
{
   if (i++ % divisor == 0)
   {
   ...
   }
}

我们立即看到i不会增加。类似地,当if语句被短路时,行为类似于上面的行为,并且后增量不会排队。

答案 1 :(得分:6)

绝对是设计。 MSDN州:

  

操作x && y对应于操作x & y,除了   如果x为false,则不评估y,因为AND的结果   无论y的值是什么,操作都是假的。这被称为   “短路”评估。

所以,你的陈述是什么并不重要,无论是否有后增量,如果它被短路都不会被评估。

答案 2 :(得分:4)

是的,这是设计的。从规范:

<强> 7.12.1 布尔条件逻辑运算符

  

操作x&amp;&amp; y被评估为(bool)x ? (bool)y : false。在   换句话说,首先评估x并将其转换为bool类型。然后,   如果x为真,则计算y并将其转换为bool类型,并且这样   成为操作的结果。否则,结果了   操作是假的

在您的代码中,y为i++ % divisor == 0,因此如果i++为空,则不会执行obj

答案 3 :(得分:2)

frameNumber不会递增,因为_visualizer != null返回false。因此,代码甚至无需检查/执行增量和模运算。

如果你转换支票(即if (_frameNumber++ % 5 == 0 && _visualizer != null)),那么_frameNumber会增加......因为实际上已经执行了操作。

所以是的:这是想要的行为,而且是设计的。

答案 4 :(得分:1)

是的,这是设计的。如果右侧评估为false,则不会评估左侧,包括可能发生的任何副作用(例如增量)

  

操作x && y对应于操作x & y,但仅当yx

时才评估true      

-source MSDN

是的,这是文档的旧版本,但语言更清晰,IMO。

如果要评估增量,请使用:

if (_visualizer != null & _frameNumber++ % _config.VisualizerUpdateFrequency == 0)
{
    ...
}

如果要在visualizer == null但不是模数:

时执行增量
var _prevFrameNumber = _frameNumber++;
if (_visualizer != null && _prevFrameNumber % _config.VisualizerUpdateFrequency == 0)
{
    ...
}