Quiz:who win in finally vs return?

废话就不多讲了,直接看看下面的例子。
1)static int Test()
        {
            int val = 1;
            try
            {
                return val;
            }
            finally
            {
                val = 2;
            }
        }
2)static int s_val;
       
static int Test()
        {
            s_val = 1;
           
try
            {
               
return s_val;
            }
           
finally
            {
                s_val = 2;
            }
        }

请问这两个例子最后的 return value 是什么?
     我们仔细看看这两个了例子就知道2)与1)的不同在于前者使用静态变量代替局部变量。那么他们之间有什么不同么?
答案是他们的return value 是一样的,都是1。
便于讲解,我们拿出他们的IL代码看看:

Test() IL
Test1() IL
这里无论是那种方式,都是生成一个隐藏变量存储返回值的,并不是直接返回变量的地址的。
如果大家多CLR的工作原理有所了解的话,应该不是很难理解,CLR对一个线程堆栈分配的是方法的局部变量和方法返回值。一个方法在线程堆栈中由它的实参开始到返回值结束。因此放回值是有自己的存储地址的。这样就可以解释上面的问题,看起来很像 { return i++ ;}

欢迎大家来拍砖。

posted on 2008-03-05 11:45 gjcn 阅读(1704) 评论(17)  编辑 收藏 所属分类: Net Framework

评论

#1楼  2008-03-05 11:53 BlueMountain      

sf   回复  引用  查看    

#2楼  2008-03-05 12:19 Anders Cui      

这个返回结果跟使用什么变量有关系吗?

我觉得此处要提起注意的是finally语句造成的结果而不是方法的返回值吧   回复  引用  查看    

#3楼  2008-03-05 12:44 guest [未注册用户]

无事找事吧   回复  引用    

#4楼 [楼主] 2008-03-05 13:01 gjcn      

@Anders Cui
对,是看造成的结果,但是要通过方法的返回值才可以看到造成的结果
  回复  引用  查看    

#5楼  2008-03-05 13:45 deerchao      

Then what happens to reference type?

FileStream fs=null;
try
{
fs = new FileStream(@"c:\aaa.txt"....);
}
finally
{
fs.Dispose();
}   回复  引用  查看    

#6楼  2008-03-05 16:31 暗香浮动      

不错。   回复  引用  查看    

#7楼 [楼主] 2008-03-05 17:26 gjcn      

@guest
现在的确比较闲,但是通过这些研究我们才能更好的了解NET嘛。个人兴趣而已
  回复  引用  查看    

#8楼  2008-03-05 20:07 volnet(可以叫我大V)      

不错的例子,讲解少了点,呵呵   回复  引用  查看    

#9楼  2008-03-06 04:49 jasduke [未注册用户]

should it be
try
{
return val;
}
finally
{
return 2;

}
  回复  引用    

#10楼 [楼主] 2008-03-06 09:02 gjcn      

@volnet(可以叫我大V)
是少了点,现在刚开始写这种文章,可能还不怎么会。
其实我想讲讲很多net底层的东西,但是由于时间和表达水平的问题一直没写。   回复  引用  查看    

#11楼  2008-03-06 11:16 kitten88 [未注册用户]

我顶   回复  引用    

#12楼  2008-03-06 11:16 acai [未注册用户]

学习了,没试过从这个层面去分析问题。
有时间说说引用类型的情况。   回复  引用    

#13楼 [楼主] 2008-03-06 11:18 gjcn      

@acai
请问想了解引用类型的什么情况?
看看我能帮你解决的?
  回复  引用  查看    

#14楼  2008-03-06 11:23 acai [未注册用户]

@gjcn
"这里无论是那种方式,都是生成一个隐藏变量存储返回值的,并不是直接返回变量的地址的。"
----由你这句话想到的。值类型可以这样,引用类型不可以吧。   回复  引用    

#15楼 [楼主] 2008-03-06 11:29 gjcn      

@acai
引用类型也是一样,CLR将一个方法分配到线程堆栈都是一样的。。

实参
局部变量
返回地址

因此这里无论是那种方式,就要看你当时return的地址。   回复  引用  查看    

#16楼  2008-03-07 14:45 hahahehe [未注册用户]

static StringBuilder Test()
{
StringBuilder strb = new StringBuilder("A");
try
{
return strb.Append("B");
}
finally
{
strb.Append("C");
}
}
这里返回的是ABC了,因为这里返回的是一个对象的引用,其实这里该对象已经给改变了。
假如把StringBuilder 改为string,那么就会是
static String Test()
{
StringBuilder strb = new StringBuilder("A");
try
{
return strb.Append("B").ToString();
}
finally
{
strb.Append("C");
}
}
这是就是AB了,因为String类型是固定空间的不可更改的类型,它的每一次表面上的更改是返回一个新的String对象。
  回复  引用    

#17楼  2008-03-10 10:52 lbq1221119      

恩 不错 顶一个

在一个trycatchfinally块中,return前finally块中的代码是一定会执行的   回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-03-10 08:35 编辑过
 
 


导航

公告

These postings are provided "AS IS" with no warranties, and confer no rights.
好无聊啊,没事做更心虚 7-29 16:26
<2008年3月>
2425262728291
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

与我联系

搜索

 

常用链接

留言簿

我参与的团队

随笔分类

随笔档案

文章分类

友情BLOG

最新评论

阅读排行榜

评论排行榜