为什么在代码行抛出异常时会执行后置递增操作?

3

今天我遇到了一种语言行为,让我感到意外。现在我很想知道原因。请看以下示例:

try
{
    worksheet.AddCell(row, cell++, image.DisplayCaption());
}
catch (NullReferenceException)
{
    cell++;
    throw;
}

在我的例子中,image 是空的,导致这一行抛出了一个 NullReferenceException; 然而,cell 仍然被递增了,当然,在 catch 块中它又被递增了。为什么第一个后置递增操作被执行了呢?此外,如果 worksheet 是空的,它会被执行吗?
谢谢,Pete
1个回答

10

方法调用的参数从左到右进行求值。

不要捕获 NullRefereneException,使用 if(image != null)。异常会导致速度变慢。

事情发生的顺序:

  1. cell 用作值参数进行复制
  2. cell 在第二个参数表达式的最后操作中增加: cell++
  3. image.DisplayCaption()
  4. worksheet.AddCell(row, <未增加的值>, <DisplayCaption() 的结果>);

由于步骤 3. 导致了一个 NullReferenceException,因此步骤 4. 不会发生。


4
不要为了速度而这样做,而是为了清晰明了的原因。你不应该使用异常来处理自己可以非常容易地测试的情况。 - Jon Skeet
谢谢,我只是用这个例子来说明行为。你的意思是如果NullReferenceException发生在后增操作符的左边,它就不会被执行? - slypete
我仍在努力解决这个问题。AddCell 怎么可能不被调用,但 cell 仍然被增加了呢?通常情况下,在 AddCell 返回之后才会发生增量。为什么在这个例子中是过早的呢? - slypete
@JakubKonecki 在这个例子中,cell 被增加了两次。 - slypete
我已经在尝试理解为什么第一个后置递增操作被执行。你和我都认为它应该被跳过。借助社区的帮助,我期待着学习为什么它没有被跳过。 - slypete
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接