本文转自 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 指令,但它可用于退出 try、filter 或 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. CSS3之边框图片border-image

    CSS3中有关border的属性,还有很多,今天我将为大家介绍一个很好玩的属性——Border-image.有了CSS3之边框图片Border-image,我们可以轻松搞定圆角,轻松搞定很多之前难搞的 ...

  2. Dom深入浅出

    Dom1级提供了一个Node接口,该接口将由Dom中所有节点类型(包括元素节点.文本节点.属性节点等12种)实现,而js是作为Node类型来实现的,js中的所有节点类型的继承自Node类型, 所以它们 ...

  3. input输入密码变黑点密文

    input输入密码加密 html代码 <form id="login-form" method="post" onsubmit="return ...

  4. 在eclipse中使用javap工具反汇编

    1.配置 Run---external tools---external tools configurations 选择Program 新建javap运行方式 设置location.workspace ...

  5. uml 在需求分析阶段的应用

    上一篇博客写了uml在软件开发过程中的应用,这以篇要详细介绍一下UML在需求分析过程中的应用. 以机房收费系统为例进行讲解,先介绍一个该系统. 首先该系统的用户分为三个等级,一般用户,操作员,管理员, ...

  6. SVN的版本日期

    SVN还可以使用版本日期来指定某个版本,日期格式使用ISO-8601标准,一般是yyyy-mm-dd hh:mm:ss.当你指定一个日期,SVN会在版本库中找到最接近这个日期的版本. SVN对日期的解 ...

  7. 写了几年代码了,苦苦追寻,应该沉淀下来了,好好研究。net底层框架,以及较好的分层框架

    几年码农了.像沉淀下来.写一下自己的分层框架,尤其是逻辑层和orm层.数据訪问层.一切靠自己.网上一大堆框架,可是感觉各有优缺点.于是萌生了自己写适合自己的底层訪问框架?亲们,你们有适合自己的框架么?

  8. PHP strpos() 函数

    定义和用法 strpos() 函数返回字符串在另一个字符串中第一次出现的位置. 如果没有找到该字符串,则返回 false. 语法 strpos(string,find,start) 参数 描述 str ...

  9. 使MySQL 支持繁体字

    要 MySQL 支持繁体字,可以将相关编码设置为 UTF8 (也叫 UTF-8).编码的设置从浏览器到表字段,一个都不能少: 浏览器设置 HTML设置 服务器 Request 对象设置 数据库连接设置 ...

  10. SQL书写技巧

    SQL书写技巧: 1.针对分区表,如果可以使用分区条件的,一定要加分区条件.分区条件的使用,可以减少不必要的数据访问,加快查询数据,如TB_CSV_ACCEPT_FLOW_OPERATOR表,以acc ...