本文转自 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. 转载Sql 获取数据库所有表及其字段名称,类型,长度

    转载原地址 http://www.cnblogs.com/Fooo/archive/2009/08/27/1554769.html SELECT (case when a.colorder=1 the ...

  2. [置顶] MapReduce 编程之 倒排索引

    本文调试环境: ubuntu 10.04 , hadoop-1.0.2 hadoop装的是伪分布模式,就是只有一个节点,集namenode, datanode, jobtracker, tasktra ...

  3. AT指令

    AT+CMGF=0  初始化 AT+IPR=115200 AT+CPAS   查询工作状态,0:可以接受AT指令,1:不能接受AT指令 ATA  应答本次电话 ATSO=2 设置2秒后自动应答 ATS ...

  4. CentOS6.5配置MySQL主从同步

    原文地址:http://www.cnblogs.com/zhongshengzhen/   修改主MySQL的配置 [root@localhost etc] vi /etc/my.cnf 添加以下配置 ...

  5. DNS服务未响应的简单解决办法

    今天晚上下班回家,打开电脑,发现打不开网页了,同一个wifi环境下,我的手机是可以连接上的,网上搜了一大推,又是重启服务,又是重新填写dns服务地址,都不管用, 该怎么办呢??. 其实发现很简单,打开 ...

  6. Quartz管理类

    package com.sihuatech.project.task.manager; import java.text.ParseException; import org.quartz.CronT ...

  7. android常见错误--INSTALL_FAILED_DEXOPT

    出现上面的问题,是由于手机的内存不足导致的,需要清理一下手机的内存,然后就可以了

  8. 使用pypi镜像源加速第三方库在线安装

    用easy_install和pip来安装第三方库很方便 它们的原理其实就是从Python的官方源pypi.python.org/pypi 下载到本地,然后解包安装. 不过因为某些原因,访问官方的pyp ...

  9. android132 360 05 手机定位

    .网络定位:根据ip地址定位,根据ip地址在实际地址数据库中查询实际地址. 缺点:动态ip导致地址不准确. .基站定位:3个基站就可以确定实际位置,定位范围是几百米到几公里不等. .GPS定位:美国卫 ...

  10. Linux下文件描述符

    http://blog.csdn.net/kumu_linux/article/details/7877770 文件描述符是一个简单的整数,用以标明每一个被进程所打开的文件和socket.第一个打开的 ...