本文转自 vipxiaotian(CSDN)

请参考下面一段简单的语句块:

1:  try
2:  {
3:      throw new Exception("new exception");
4:  }
5:  catch(Exception ex)
6:  {
7:      return;
8:  }
9:  finally
10:  {
11:      Console.WriteLine("a");
12:  }

大家有没有想过执行到第七步之后会出现什么结果?line7是一条return语句,按道理来说return语句的作用就是跳出当前函数并继续调用地址的下一条语句,那么说就不执行finally,但是我想大家应该都记得finally的作用:确保有无异常的情况下finally块中的语句都能执行……于是,矛盾就这样产生鸟。。。

在继续下去看答案之前,亲爱的读者们,你们觉得会是什么结果呢?finally会不会执行呢?请先思考一下再看答案。

既然在程序层看不出猫腻,那么我们不妨深入IL层去挖掘一下,上面代码的IL是这样子地:

.try
  {
    .try
    {
      IL_0000:  ldstr      "new exception"
      IL_0005:  newobj     instance void [mscorlib]System.Exception::.ctor(string)
      IL_000a:  throw
    }  // end .try
    catch [mscorlib]System.Exception 
    {
      IL_000b:  stloc.0
      IL_000c:  leave.s    IL_0019
    }  // end handler
  }  // end .try
  finally
  {
    IL_000e:  ldstr      "a"
    IL_0013:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_0018:  endfinally
  }  // end handler
  IL_0019:  ret

请注意上面上面黄色部分代码,在catch块中,使用了leave.s这条命令来跳转到IL_0019这一行,而0019这一行正是ret命令,看起来……应该不会执行到finally才对~~难道说,从catch块就直接跳出了?!

我想该是时候去弄明白leave.s这条命令的作用了,看看Microsoft给出的定义:

格式 汇编格式 说明
DE < int8 > leave.s target 退出受保护的代码区域(短格式)。

没有为此指令指定任何堆栈转换行为。

leave.s 指令无条件将控制转移到传递的目标指令,这表示为距当前指令之后的指令的开始处的 1 字节有符号偏移量。

leave.s 指令类似于 br 指令,但它可用于退出 tryfilter 或 catch 块,而一般分支指令只能在此类块中使用以在其内部转移控制。leave.s 指令清空计算堆栈并确保执行周围适当的 finally 块。

不能使用 leave.s 指令退出 finally 块。为了简化异常处理程序的代码生成,一个有效的方法是在 Catch 块的内部使用 leave.s 指令将控制转移到关联的 try 块中的任何指令。

如果指令有一个或多个前缀代码,则只能将控制转移到其中的第一个前缀。

OK,至此,一切明了了~~leave.s会确保finally块的执行,所以,即使在catch中使用了return语句想直接跳出,还是会先执行finally再return的

C#:在catch中return,会执行finally吗?的更多相关文章

  1. 我敢说你不一定完全理解try 块,catch块,finally 块中return的执行顺序

    大家好,今天我们来讲一个笔试和面试偶尔都会问到的问题,并且在工作中不知道原理,也会造成滥用. 大家可能都知道,try 块用来捕获异常,catch块是处理try块捕获的异常,finally 块是用来关闭 ...

  2. java-try catch中return在finally之前 还是之后执行

    finally语句在return语句执行之后return返回之前执行的. finally块中的return语句会覆盖try块中的return返回. 如果finally语句中没有return语句覆盖返回 ...

  3. try-catch-finally中return的执行情况分析

    try-catch-finally中return的执行情况分析: 1.在try中没有异常的情况下try.catch.finally的执行顺序 try --- finally 2.如果try中有异常,执 ...

  4. try catch finally中return的执行顺序

    下面说一下try{ } catch{}中有return的情况 究竟是哪个return起作用的 话不多说 上代码 1 try中有return的情况 //普通方法 public static int hh ...

  5. try-catch-finally中return的执行情况

    在try中没有异常的情况下try.catch.finally的执行顺序 try--- finally 如果try中有异常,执行顺序是try--- catch --- finally 如果try中没有异 ...

  6. Java的finally语句在try或catch中的return语句执行之后还是之前?

    import java.util.HashMap; import java.util.Map; public class FinallyDemo1 { public static void main( ...

  7. JAVA中try、catch、finally带return的执行顺序总结

    异常处理中,try.catch.finally的执行顺序,大家都知道是按顺序执行的.即,如果try中没有异常,则顺序为try→finally,如果try中有异常,则顺序为try→catch→final ...

  8. 当try、catch中有return时,finally中的代码会执行么?

    今天,看到一个面试题: try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 我们用代码来验证下: public static void mai ...

  9. try--catch--finally中return返回值执行的顺序(区别)

    1.try块中没有抛出异常,try.catch和finally块中都有return语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public static int ...

随机推荐

  1. Android实例-如何使用系统剪切板(XE8+小米2)

    结果: 发现个问题,就是粘贴时会清除之前的信息. unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, S ...

  2. nyoj 17 单调递增最长子序列

    单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列就是abdf,长度为4   输入 ...

  3. 在线性级别时间内找出无序序列中的第k个元素

    在一个无序序列中找出第k个元素,对于k很小或者很大时可以采取特殊的方法,比如用堆排序来实现 .但是对于与序列长度N成正比的k来说,就不是一件容易的事了,可能最容易想到的就是先将无序序列排序再遍历即可找 ...

  4. centos6下安装部署hadoop2.2

    环境准备1.操作系统:centos6.0 64位2.hadoop版本:hahadoop-2.2.0 安装和配置步骤具体如下:1.主机和ip分配如下     ip地址                  ...

  5. AS问题解决系列3—iCCP: Not recognizing known sRGB profile

    http://my.oschina.net/1pei/blog/479162 摘要 本文解决了Android Studio 1.2.2下编译期间出现的libpng warning: iCCP: Not ...

  6. 汉语转拼音pinyin4j

    分享一个将汉语转成拼音的工具包:pinyin4j-2.5.0.jar,下载地址:http://download.csdn.net/detail/abc_key/7629141 使用例如以下代码 imp ...

  7. 【47】请使用traits classes表现类型信息

    1.考虑下面的需求,对迭代器移动d个单位.因为不同类型的迭代器,能力不同,有的迭代器(vector,deque内置迭代器)可以一步到位移动到指定位置,有的迭代器(list内置迭代器)必须一步一步移动, ...

  8. Android ListView快速定位(三)

    方法三: android:fastScrollEnabled="true" 这个很简单,只要把属性设置了,就可以起作用了 不过这个滑块比较丑,当然网上也有自定义图片的例子. 参考 ...

  9. sphinx中过滤的简单介绍

    1.过滤字符串为空的一些记录的话,可以在sql_query中直接加上where来限制,如: sql_query  = \  SELECT a.location_id as id,a.location_ ...

  10. TIME-WAIT和CLOSE-WAIT

    系统调优,你所不知道的TIME_WAIT和CLOSE_WAIT 2016-03-11 运维帮 来源微信订阅号:大房说 作者:大房 你遇到过TIME_WAIT的问题吗?   我相信很多都遇到过这个问题. ...