网上看到过一个面试题,就是一个整型变量在try{}中被修改为5,然后return 该变量,然后finally{} 里面将该变量自加一。问函数的返回值。
代码1:
using System;
using System.Collections.Generic;
using System.Text;
namespace Finally
{
class Program
{
static void Main(string[] args)
{
int z = func1();
System.Console.WriteLine(z.ToString());
}
static public int func1()
{
int i = 1;
try
{
i = 5;
return i;
}
finally
{
i += 1;
}
}
}
}
返回值为5,而不是6,执行顺序是先保存返回值(i=5),然后再执行finally,再返回。
直接在vs.net2005里面反汇编就可以看到,return被拆分了,先保存返回值,然后再执行finally。在finally里面变量i被修改了,但是返回值并没有受影响。
static public int func1()
{
00000000 push ebp
00000001 mov ebp,esp
00000003 push edi
00000004 push esi
00000005 push ebx
00000006 sub esp,34h
00000009 xor eax,eax
0000000b mov dword ptr [ebp-10h],eax
0000000e xor eax,eax
00000010 mov dword ptr [ebp-1Ch],eax
00000013 cmp dword ptr ds:[00AE885Ch],0
0000001a je 00000021
0000001c call 792610E6
00000021 xor edx,edx
00000023 mov dword ptr [ebp-3Ch],edx
00000026 xor edx,edx
00000028 mov dword ptr [ebp-40h],edx
0000002b nop
int i = 1;
0000002c mov dword ptr [ebp-3Ch],1
try
{
00000033 nop
i = 5;
00000034 mov dword ptr [ebp-3Ch],5
return i;
0000003b mov eax,dword ptr [ebp-3Ch]
0000003e mov dword ptr [ebp-40h],eax
00000041 nop
00000042 mov dword ptr [ebp-20h],0
00000049 mov dword ptr [ebp-1Ch],0FCh
00000050 push 0E31283h
00000055 jmp 00000057
}
finally
{
00000057 nop
i += 1;
00000058 inc dword ptr [ebp-3Ch]
}
0000005b nop
0000005c pop eax
0000005d jmp eax
0000005f nop
}
00000060 mov eax,dword ptr [ebp-40h]
00000063 lea esp,[ebp-0Ch]
00000066 pop ebx
00000067 pop esi
00000068 pop edi
00000069 pop ebp
0000006a ret
0000006b mov dword ptr [ebp-1Ch],0
00000072 jmp 0000005F
如果把int型改成StringBuilder呢? 代码如下
using System;
using System.Collections.Generic;
using System.Text;
namespace Finally
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = func1();
System.Console.WriteLine(sb.ToString());
}
static public StringBuilder func1()
{
StringBuilder sb = new StringBuilder();
try
{
sb.Append("FiredFish");
return sb;
}
finally
{
sb.Append("IncnBlogs");
}
}
}
输出结果为 “FiredIncnBlogs”
IncnBlogs是在finally块里面被加上的,
因为int型式数值类型,返回时是值传递,StringBuilder是类对象,返回值是引用传递的,在finally块中操作的和return返回的是同一个StringBuilder对象。
