程式寫久了對執行流程會總有些自以為是的邏輯,而這些自己為是的可能讓你產生難以找尋的Bug.比如說在任何地方return就是直接回到原呼叫端的流程,但是這個return在try block中可能不是想像中的那樣。
以下範例讓我們看看return之後程式跑到那去?
// returnInTryBlock : 是否在try block 中 return
void TestReturnInTryBlock(bool returnInTryBlock)
{
Console.WriteLine ("開始TestReturnInTryBlock");
try
{
Console.WriteLine ("開始Try Block");
if (returnInTryBlock)
{
Console.WriteLine ("returnInTryBlock is true");
Console.WriteLine ("即將 return");
return;
}
else
{
Console.WriteLine ("returnInTryBlock is flase");
}
Console.WriteLine ("結束Try Block");
}
finally
{
Console.WriteLine ("開始Finally block");
// some code for clean up
Console.WriteLine ("結束Finally block");
}
Console.WriteLine ("結束TestReturnInTryBlock");
}
測試一下try block中沒有執行到return的流程,如預期的在沒有exception的情況下,完整的執行完try block後接著執行finally block,執行完finally block後再執行try statements之後的流程,也就是Console.WriteLine ("結束TestReturnInTryBlock");
最後就離開了TestReturnInTryBlock
程序回到了上一層的叫用程序。
Console.WriteLine ("程式開始");
TestReturnInTryBlock (false);
Console.WriteLine ("程式結束");
//=== 執行結果
程式開始
開始TestReturnInTryBlock
開始Try Block
returnInTryBlock is flase
結束Try Block
開始Finally block
結束Finally block
結束TestReturnInTryBlock
程式結束
再來測試try block中有執行到return的流程,原本預期的在沒有exception的情況下,完整的執行到return時會離開了TestReturnInTryBlock
程序回到了上一層的叫用程序,但執行結果並非如此,而是執行到return後依然會跳躍到finally block , 完整執行完finally block 後才會直正的return回上一層的程序。
Console.WriteLine ("程式開始");
TestReturnInTryBlock (true);
Console.WriteLine ("程式結束");
//=== 執行結果
程式開始
開始TestReturnInTryBlock
開始Try Block
returnInTryBlock is true
即將 return
開始Finally block
結束Finally block
程式結束
所以我以前在使用try catch finally這一組的 statements常常畫蛇添足,為了要釋放之前叫用如資料庫連線的一些資源,會額外在try block 中有return情況前多叫用了和 finally block中相同的程式一次,現在知道了,以後就只要安心的在try block中return就好了,程式流程一定會走到finally block完成後return回上一層的程序。