问题提出

       try
{
return x;
}
finally
{
x = null;
}

上面这段代码到底怎么执行的?

try..catch..finally 介绍

在MSDN中,try..catch..finally 的介绍如下:

  • finally 块用于清除 try 块中分配的任何资源,以及运行任何即使在发生异常时也必须执行的代码。 控制总是传递给 finally 块,与 try 块的退出方式无关。
  • catch 用于处理语句块中出现的异常,而 finally 用于保证代码语句块的执行,与前面的 try 块的退出方式无关。
  • catch 和 finally 一起使用的常见方式是:在 try 块中获取并使用资源,在 catch 块中处理异常情况,并在 finally 块中释放资源。

典型用法:

     void ReadFile(int index)
{
string path = @"c:\users\public\test.txt";
char[] buffer = new char[]; StreamReader file = new StreamReader(path);
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (IOException e)
{
Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}
finally
{
if (file != null)
{
file.Close();
}
}
}

通常 finally 中的代码只负责清理资源。

那么,如果 finally 中包含业务逻辑,try..finally..的执行顺序会对业务逻辑有怎样的影响呢?

try..finally 的执行顺序

回到问题,

    void Main()
{
Console.WriteLine(TestTryFinally());
} public string TestTryFinally()
{
string x = "init";
try
{
x = "try";
return x;
}
finally
{
x = "finally";
}
}

这里的执行顺序是:

  1. 执行 return 之前的代码
  2. 对 return 语句求值
  3. 执行 finally 中的代码
  4. 在第 2 步中的求值结果被返回

所以,具体是否对返回值有影响,得看 x 变量的类型。如果是不可变类型,则 finally 中的代码对 return 的求值结果没有任何影响。而如果是可变类型,则 finally 中的代码会改变 return 求值结果的内容。

上述代码,在 x 类型为 string 时,返回值为 "try"。

查看 IL 代码,

 IL_0000:  ldarg.
IL_0001: call UserQuery.TestTryFinally
IL_0006: call System.Console.WriteLine TestTryFinally:
IL_0000: ldstr "init"
IL_0005: stloc. // x
IL_0006: ldstr "try"
IL_000B: stloc. // x
IL_000C: ldloc. // x
IL_000D: stloc. // CS$1$0000
IL_000E: leave.s IL_0017
IL_0010: ldstr "finally"
IL_0015: stloc. // x
IL_0016: endfinally
IL_0017: ldloc. // CS$1$0000
IL_0018: ret

发现在 stloc.1 处会创建 CS$1$0000 临时变量来存储 return 返回值。

从程序集反编译代码查看结果,程序已经被优化。

 // ConsoleApplication11_TryFinallyTest.Program
public string TestTryFinally()
{
string result;
try
{
string x = "try";
result = x;
}
finally
{
}
return result;
}

更多测试结果

 using System;
using System.Text; namespace ConsoleApplication11_TryFinallyTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(MethodA());
Console.WriteLine(a); Console.WriteLine(MethodB().ToString());
Console.WriteLine(b.ToString()); Console.WriteLine(MethodC());
Console.WriteLine(c); Console.WriteLine(MethodD().ToString());
Console.WriteLine(d.ToString()); Console.WriteLine(MethodE().ToString());
Console.WriteLine(e.ToString()); Console.ReadKey();
} static string a;
static string MethodA()
{
try
{
a = "tryA";
return a;
}
finally
{
a = "finallyA";
}
} static StringBuilder b = new StringBuilder();
static StringBuilder MethodB()
{
try
{
b.Append("tryB");
return b;
}
finally
{
b.Append("finallyB");
}
} static int c;
static int MethodC()
{
try
{
c = ;
return c;
}
finally
{
c = ;
}
} static Person d;
static Person MethodD()
{
try
{
d = new Person() { Name = "tryD" };
return d;
}
finally
{
d = new Person() { Name = "finallyD" };
}
} static Person e;
static Person MethodE()
{
e = new Person() { Name = "E" };
try
{
e.Name = "tryE";
return e;
}
finally
{
e.Name = "finallyE";
}
} class Person
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
}
}

参考资料

Try..Finally..相信自己的眼睛的更多相关文章

  1. [No0000A3]护眼谎言大揭秘,选择正确的方式保护眼睛!

    当眼睛因为过度劳累而状况频出的时候,许多人没有选择极目远眺.眼保健操.充分睡眠等简单易行的养眼方式,而是求助于各种护眼工具.于是,在视疲劳成为常见眼病之后,护眼市场产品层出不穷:护眼灯.眼贴.眼保仪. ...

  2. 取消ie浏览器edge浏览器输入框右边的叉和眼睛

    在ie高版本浏览器和edge浏览器里type为text和password的input框在输入时右边会出现×和眼睛,如果需要清除,方法如下: 首先在页面头部声明兼容性模式 <meta http-e ...

  3. 你的眼睛背叛你的心:解决 .NET Core 中 GetHostAddressesAsync 引起的 EnyimMemcached 死锁问题

    在我们将站点从 ASP.NET + Windows 迁移至 ASP.NET Core + Linux 的过程中,目前遇到的最大障碍就是 —— 没有可用的支持 .NET Core 的 memcached ...

  4. HTML5 Canvas眨眼睛动画

    效果请看: http://keleyi.com/a/bjad/p9exlcwi.htm 请使用支持HTML5的浏览器查看效果. 以下是代码: <html> <body> < ...

  5. 保护眼睛(ubuntu 和 chrome)

    chrome 安插件https://chrome.google.com/webstore/detail/%E4%BF%9D%E6%8A%A4%E7%9C%BC%E7%9D%9B/fgadnbmmoln ...

  6. [转]保护眼睛的Windows和IE、Firefox、谷歌等浏览器颜色设置

    保护眼睛的Windows和IE.Firefox.谷歌等浏览器颜色设置  长时间在电脑前工作,窗口和网页上的白色十分刺眼,眼睛很容易疲劳,也容易引起头痛,其实我们可以通过设置Windows窗口和软件的颜 ...

  7. 保护眼睛,把常用软件的背景设置成Dark

    每天长时间使用电脑,很多软件的背景都是白色,久看对眼睛不好. 1)Google Chrome,WebDev/看新闻/看邮件/写博客.使用Stylish插件和Global Dark Style,效果相当 ...

  8. [python]计算机使用过程中,眼睛强制休息

    前言 现在的电脑族们,在使用电脑的过程中,常常忘记了时间的流逝,要么忙碌在电视剧的观看中,要么忙碌在工作中,要么忙碌在游戏中,往往忽视了对眼睛的正常保护,让眼睛能够在空闲的时候获得足够的休息时间. 我 ...

  9. NodeJs爬虫—“眼睛好看是一种什么样的体验?”

    逛知乎的时候经常看见有好多的福利贴(钓鱼贴),这不最近又让我发现了一个——眼睛好看是一种什么样的体验是一种怎么样的体验呢?我决定把答案里的照片都下到我的电脑里好好体验一下,怎么做呢,一张一张下好麻烦, ...

  10. Win7下如何设置护眼的电脑豆沙绿界面?保护眼睛的颜色设置教程

    关爱心灵的窗户——眼睛! 随着科技发展,使用电脑的人越来越多,由于使用电脑时间过长,我们的眼睛也越发容易疲劳,干燥.如何才能使电脑对人眼的伤害减小到最 小. 小编建议大家可以把窗口背景色设置成护眼色. ...

随机推荐

  1. VBS中对Error的处理

    VBScript语言提供了两个语句和一个对象来处理"运行时错误",如下所示: On Error Resume Next语句 On Error Goto 0语句 Err对象 简单介绍 ...

  2. Ruby-Array数组

    1.创建数组 a=Array.new(6,obj=nil)  #=> [nil, nil, nil, nil, nil, nil] 设置默认值 a=Array.new(6)           ...

  3. android通过gradle打包

    这里是最简单的打包方法,实际上gradle的语法是groovy,可以通过编写脚本实现更智能的构建,这个我还不懂==,等我学习了解后,单独整理一个gradle的随笔,这里先应付打包吧   环境要求 安装 ...

  4. [html]选项卡效果

    晨间新闻 午间新闻 晚间新闻 视频新闻 <!doctype html> <html> <head> <meta charset="UTF-8&quo ...

  5. 单片机TM4C123学习(八):SPI接口D/A

    1.头文件和变量定义(不是很清楚) #include "driverlib/ssi.h" #include "driverlib/i2c.h" #include ...

  6. Linux下一些文件夹的含义

    在 Linux系统里面,"分区",被称作"挂载点",简单明了的说,"挂载点"意思就是:把一部分硬盘容量,"分"成一个文件 ...

  7. markdown编辑器实现笔记

    1.js代码放在head和body的区别 <html> <head> <script src="https://cdnjs.cloudflare.com/aja ...

  8. php中or的含义

    or其实是Php中的短路或 经常看到这样的语句: $file = fopen($filename, r) or die("抱歉,无法打开: $filename"); or在这里是这 ...

  9. 20145225《Java程序设计》 2015—2016年学期课程总结

    20145225<Java程序设计> 2015—2016年学期课程总结 读书笔记链接汇总 1.2016年2月25日 <Java程序设计>课程准备之问卷调查 摘要: 一.你对自己 ...

  10. HTTP请求响应对照表

    1)请求(客户端->服务端[request]) GET(请求的方式) /books/java.html(请求的目标资源) HTTP/1.1(请求采用的协议和版本号) Accept: */*(客户 ...