【原创】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--

原文地址:https://www.cnblogs.com/fangwenyu/p/1589029.html