又是星期一,我对C#基础知识有疑问。如果方法抛出异常,方法返回值会发生什么?
具体来说,当在方法中抛出异常并且对返回值有什么影响时,“引擎盖下”会发生什么?在这种情况下,如何在内部计算返回值?
假设有两种情况:一种情况,其中返回值的类型为int
,另一种类型为object
。发生异常时,是否会在内部调用default(T)
?在这种情况下,我应该考虑类型int
的返回值是零而对象的返回值是null
吗?
答案 0 :(得分:8)
简短而过于简化的答案是它不会返回任何内容。代码在发生异常的地方“中断”并且在堆栈中向下移动直到有东西捕获它。
即使您做碰巧捕获异常,您尝试使用方法的返回值初始化的变量仍将保持调用方法之前的变量:
var i = 5;
try
{
i = MyMethodThatThrowsAnException();
}
catch
{
// at this point, the i variable still equals 5.
}
我应该提一下,如果它抛出异常,你真的不应该担心函数的返回值。如果你这样做,那么你可能做错了,比如使用exceptions as flow control。
答案 1 :(得分:2)
进行重大简化:
当抛出异常时,.Net CLR开始搜索堆栈,直到找到可以处理异常的异常处理程序。
此时,调整堆栈指针,以便使用正确参数从正确的点运行异常处理代码。 (异常本身捕获抛出点处的堆栈信息,以便在捕获点提供该信息。)
实际上,CLR执行了一种“goto”,它跳过任何代码,这些代码可能一直在使用抛出异常的函数的任何返回值 - 因此返回值根本不相关。在此方案中永远不会创建,使用或需要它。
请注意,这是对实际发生的事情的极大简化,但要点拿走的主要内容是发生一种复杂的goto - 遍历堆栈帧。这就是使返回值无关紧要的原因。