【原创】Using and IL
Abstract: 通过查看IL来了解下声明在using语句中的对象是在try语句外面实例化还是在try里面实例化。
举例来说,下面的c# code
1: using(FileStream aFs = new FileStream(@"c:\test.txt", FileMode.Open))
2: {
3: // Do noting...
4: }
是对应下面的那种情况呢?
(1)
1: FileStream aFs = null;
2: try
3: {
4: aFs = new FileStream(@"c:\test.txt", FileMode.Open);
5: }
6: finally
7: {
8: if (aFs != null)
9: {
10: aFs.Close();
11: }
12: }
(2)
1: FileStream aFs = new FileStream(@"c:\test.txt", FileMode.Open);
2: try
3: {
4:
5: }
6: finally
7: {
8: if (aFs != null)
9: {
10: aFs.Close();
11: }
12: }
其实通过查看Using语句对应的IL就很清楚了
1: .locals init (
2: [0] class [mscorlib]System.IO.FileStream aFs,
3: [1] bool CS$4$0000)
4: L_0000: nop
5: L_0001: ldstr "c:\\test.txt"
6: L_0006: ldc.i4.3
7: L_0007: newobj instance void [mscorlib]System.IO.FileStream::.ctor(string, valuetype [mscorlib]System.IO.FileMode)
8: L_000c: stloc.0
9: L_000d: nop
10: L_000e: nop
11: L_000f: leave.s L_0021
12: L_0011: ldloc.0
13: L_0012: ldnull
14: L_0013: ceq
15: L_0015: stloc.1
16: L_0016: ldloc.1
17: L_0017: brtrue.s L_0020
18: L_0019: ldloc.0
19: L_001a: callvirt instance void [mscorlib]System.IDisposable::Dispose()
20: L_001f: nop
21: L_0020: endfinally
22: L_0021: nop
23: L_0022: ret
24: .try L_000d to L_0011 finally handler L_0011 to L_0021
注意L_0007对应的实例化FileStream对象aFs在try语句之外(L_00d to L_0011),因此很显然using语句中的对象初始化其实是在进入try语句之前执行的。
Conclusion: Dig a little deeper to IL to see what happens behind the scenes.
--End--
--------------------------------------
Regards,
FangwenYu