问题提出

       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. CIDR-Address介绍

    CIDR是一种用二进制表示法来代替十进制表示法的新方法. IP地址有“类”的概念,/8掩码是A类,/16掩码是B类,/24掩码是C类等等.但是/12,/18,/25呢?这就是无类的概念了,CIDR的作 ...

  2. word 批量删除书签

    打开word    按住alt+F11 进入vba 界面 Sub test() Dim MyBk As Bookmark For Each MyBk In ActiveDocument.Bookmar ...

  3. fastJson java后台转换json格式数据

    什么事JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Progra ...

  4. linux档案与文件的的压缩与打包

    本文涉及的命令:gzip.zcat.bzip2.bzcat.tar.dump.restore.mkiosfs.cdrecord.dd.cpio. 概念: 几种基础压缩的概念: 计算机最小单位是字节,但 ...

  5. SAP 常用函数

    1. 访问本地 或别的服务器上文件 函数 CALL METHOD CL_GUI_FRONTEND_SERVICES=>EXECUTE       EXPORTING         DOCUME ...

  6. JS向光标指定位置插入内容

    方法: function insertHtmlAtCaret(html) { var sel, range; if (window.getSelection) { // IE9 and non-IE ...

  7. shell脚本学习(一)

    Shell脚本最常用于系统管理工作,或者用于结合现有的程序以完成小型.特定的工作. Shell的特点有: 1. 简单性 2. 可移植性 3. 开发容易 [什么是shell] 简单点理解,就是系统跟计算 ...

  8. 在ASP.NET中引用自定义提示框

    在html网页中自定义提示框 正文: 在一般的B/S架构中项目,与用户的交互信息是非常重要的.在一般的情况下,设计人员都在把用户信息呈现在html中,用div和span去弹出相关信息.对于一般的情况而 ...

  9. php变量判断为空的几种方法

    1.isset  主要用来判断变量是否被初始化过 注意:当使用isset来判断数组元素是否被初始化过时,它的效率比array_key_exists高4倍左右 2.empty  可以将值为 " ...

  10. iOS模拟各种网络状态

    在iOS开发中我们有在各种不同网络状态下测试app运行状态的需求.苹果给我们提供了在模拟器和真机状态下,模拟各种网络状态的软件. 在模拟器中 苹果提供的模拟网络状态的工具官网地址下载该工具需要登录Ap ...