本文转自 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. hdu 5533 Dancing Stars on Me

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5533 Dancing Stars on Me Time Limit: 2000/1000 MS (Ja ...

  2. iframe中的各种跳转方法

    iframe中的各种跳转方法(转)   一.背景A,B,C,D都是jsp,D是C的iframe,C是B的iframe,B是A的iframe,在D中跳转页面的写法区别如下. 二.JS跳转window.l ...

  3. Delphi- ini文件的读写操作

    一.读INI文件示例 procedure TForm1.FormCreate(Sender: TObject); Var MyIni :Tinifile; glAppPath :string; beg ...

  4. 如何使用validate.js进行动态添加和移除表单验证信息

    表单是我们在开当中的常客,那么对表单的验证也是必须的,那么如何实现动态给表单添加验证规则呢? 方法: 1,动态添加验证规则 // 添加$("#addConnectUser").ru ...

  5. ZZTHX-Androidannotations框架联想

    我们首先来看一段代码: 在android开发中findViewById是最常用的一个方法,用来实例化页面上的控件,基本上每个控件都需要调用一次的,加入我们页面上有100个需要使用,那么findView ...

  6. Ant-关键元素(笔记一)

    需求:使用ant脚本在控制台输出一句话 <?xml version="1.0" encoding="utf-8"?> <project nam ...

  7. WinForm开发中针对TreeView控件改变当前选择节点的字体与颜色

    本文转载:http://www.cnblogs.com/umplatform/archive/2012/08/29/2660240.html 在B/S开发中,对TreeView控件要改变当前选中节点的 ...

  8. Ubuntu 安装 Courier New字体

    apt-get install ttf-mscorefonts-installer  它的本质是安装 Courier New字体 安装的时候会出现一个协议 按TAB键 ,可以选中<确定>按 ...

  9. 将string转换成UTF8在进行请求

    在请求服务器时,如果参数中带有中文字符.就会报参数格式错误,需要将其转换成UTF8 @interface NSString (NSURLUtilities) /* Adds all percent e ...

  10. hibernate 使用C3P0数据源

    1.导入jar包: hibernate-release-4.3.5.Final/lib/optional/*.jar 2.增加配置: <!-- 配置 C3P0 数据源 --> <pr ...