2

所以,如果我有这样的表达:

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

and objis null, theni永远不会增加。如果我使用

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();

        }

    }
4

5 回答 5

6

后增量只是对语句的后评估。由于该语句从未被评估(它是短路的)它被跳过。

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

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

在这里,我们立即看到i不会增加。同样,当if语句短路时,行为与上述类似,并且后增量不排队。

于 2013-06-18T20:52:26.790 回答
6

这绝对是设计使然。MSDN状态:

该操作x && y对应于操作x & y,只是如果 x 为假,则不计算 y,因为无论 y 的值是多少,AND 操作的结果都是假的。这称为“短路”评估。

所以,不管你的语句是什么,不管它是否有后增量,如果它被短路,它就不会被评估。

于 2013-06-18T20:54:50.930 回答
4

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

7.12.1 布尔条件逻辑运算符

操作 x && y 被评估为(bool)x ? (bool)y : false。换句话说,首先评估 x 并将其转换为类型 bool 。然后,如果 x 为 true ,则评估 y 并将其转换为类型 bool ,这将成为操作的结果。否则,运算结果为假

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

于 2013-06-18T20:59:18.307 回答
2

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

如果您将检查切换(即if (_frameNumber++ % 5 == 0 && _visualizer != null))然后_frameNumber会增加......因为实际上执行了操作。

所以是的:这是想要的行为,它是设计使然。

于 2013-06-18T20:57:22.657 回答
1

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

操作x && y对应于操作x & y,除了y仅当xtrue

——来源MSDN

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

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

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

如果您想执行增量,即使visualizer == null不是模数:

var _prevFrameNumber = _frameNumber++;
if (_visualizer != null && _prevFrameNumber % _config.VisualizerUpdateFrequency == 0)
{
    ...
}
于 2013-06-18T20:55:22.043 回答