短路计算跳过条件的前/后增量
本文关键字:计算 条件 短路 | 更新日期: 2023-09-27 18:18:53
那么,如果我有一个表达式:
if (obj != null && i++ % divisor == 0)
{
....
}
且obj
为null
,则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();
}
}
这绝对是设计的结果。MSDN州:
x && y
与x & y
对应如果x为假,y不会被求值,因为与运算的结果不管y的值是多少,操作都是假的。这被称为"短路"评估。
所以,不管你的语句是什么,不管它是否有后增量,如果短路,它不会被求值
后增量只是语句的后求值。由于该语句从不求值(它是短路的),因此它被跳过。
一种更直观的思考方式是将if语句想象为嵌套的:
if (obj != null)
{
if (i++ % divisor == 0)
{
...
}
}
这里我们立即看到i
不会被加1。类似地,当if
语句短路时,其行为与上述类似,并且后增量不排队。
是的,这是设计。来自规范:
7.12.1布尔条件逻辑运算符
操作x &&y求值为
(bool)x ? (bool)y : false
。在换句话说,x首先被求值并转换为bool类型。然后,如果x为真,则计算y并将其转换为bool类型成为操作的结果。的结果操作为false
在你的代码中,y是i++ % divisor == 0
,所以如果obj
为空,i++
将不会被执行。
frameNumber不加1,因为_visualizer != null
返回false。因此,代码甚至不需要检查/执行自增和取模操作。
如果你切换检查(即if (_frameNumber++ % 5 == 0 && _visualizer != null)
),那么_frameNumber
会增加…因为实际执行了操作。
所以,是的:这是想要的行为,这是设计
是的,这是设计。如果右边的计算结果为false
,则永远不会计算左边,包括可能发生的任何副作用(例如增量)
操作
x && y
对应于操作x & y
,但只有当x
为true
时才对y
求值本;源MSDN
是的,这是旧版本的文档,但是语言更清晰,IMO。
如果你想计算增量,可以使用:
if (_visualizer != null & _frameNumber++ % _config.VisualizerUpdateFrequency == 0)
{
...
}
如果你想在visualizer == null
时执行自增操作,而不是模数操作:
var _prevFrameNumber = _frameNumber++;
if (_visualizer != null && _prevFrameNumber % _config.VisualizerUpdateFrequency == 0)
{
...
}