问题提出

       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. HeartBeat的一些介绍和功能上的一些总结

    HeartBeat的作用: 通过HeartBeat,可以将资源(IP以及程序服务等资源)从一台已经故障的计算机快速转移到另一台正常运转的机器上继续提供服务,一般称之为高可用的服务.在实际的生产应用场景 ...

  2. 进阶篇:以IL为剑,直指async/await

    接上篇:30分钟?不需要,轻松读懂IL,这篇主要从IL入手来理解async/await的工作原理. 先简单介绍下async/await,这是.net 4.5引入的语法糖,配合Task使用可以非常优雅的 ...

  3. 《深入理解Nginx》阅读与实践(三):使用upstream和subrequest访问第三方服务

    本文是对陶辉<深入理解Nginx>第5章内容的梳理以及实现,代码和注释基本出自此书. 一.upstream:以向nginx服务器的请求转化为向google服务器的搜索请求为例 (一)模块框 ...

  4. JAXB 2.0 API is being loaded from the bootstrap classloader

    在使用webservice,mule esb等需要jaxb的项目里经常会出现 JAXB 2.0 API is being loaded from the bootstrap classloader这个 ...

  5. 添加和删除hadoop集群中的节点

    参见 http://www.cnblogs.com/tommyli/p/3418273.html

  6. Ruby-调用windows窗体

    发现SharpDevelop 也支持Ruby ,特别是可以直接把winform的控件直接用在 require "mscorlib" require "System.Win ...

  7. 一款好用的杀毒软件-pchunter64

    360真是猛,用system权限运行了一坨后台进程.今天清理系统盘想删掉360发现根本没权限.进程又杀不掉. 最后使用 pchuter64 强行干掉了360 避免了 重装系统的尴尬.360作为世界第一 ...

  8. Google上的Cookie Matching

    Cookie Matching This guide explains how the Cookie Matching Service enables you to make more effecti ...

  9. js中实现字母大小写转换

    js中实现字母大小写转换主要用到了四个js函数: 1.toLocaleUpperCase  2.toUpperCase3.toLocaleLowerCase4.toLowerCase 下面就这四个实现 ...

  10. 解决winrar压缩软件弹出广告

    最近winrar每次打开压缩包就会弹出一个广告,那是因为winrar是收费软件,注册了就没有广告了.下面我教大家怎么注册来屏蔽广告. 解决方法 1.新建一个txt文件并命名为"rarreg. ...