1. 程式人生 > >關於C# using 作為定義範圍的問題

關於C# using 作為定義範圍的問題

昨天我們團隊的一位同學問到我關於using關鍵字作為定義範圍使用自動釋放物件是如何工作的問題.
其實using關鍵字作為範圍定義使用,自動完成釋放工作完全是一種語法層面的簡化. 首先我們按照標準using作為範圍使用的方法編寫一個程式;
public class A : IDisposable
 {
  /// <summary>
  /// 成員
  /// </summary>
  private int i;
  /// <summary>
  /// 建構函式
  /// </summary>
  public A()
  {
   i = 0;
  }
  /// <summary>
  /// 函式方法
  /// </summary>
  /// <returns></returns>
  public int GetValue()
  {
   return i;
  }
  /// <summary>
  /// 銷燬函式
  /// </summary>
  public void Dispose()
  {
//銷燬操作
  }
 }
 class Demo
 {
  /// <summary>
  /// 應用程式的主入口點。
  /// </summary>
  static void Main(string[] args)
  {
   using(A a = new A())
   {
    Console.WriteLine(a.GetValue());
   }
  }
 } 其實這裡關於使用using作為物件範圍要求函式實現具有IDisposable介面Dispose函式. 為什麼需要這樣呢?可以肯定在這個過程中必定自動呼叫了Dispose函式,居然如何實現的呢?
我們使用ildasm反彙編IL看一下上面這個程式的中間程式碼:
 .try
  {
    IL_0006:  ldloc.0
    IL_0007:  callvirt   instance int32 ConsoleApplication1.A::GetValue()
    IL_000c:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_0011:  leave.s    IL_001d
  }  // end .try
  finally
  {
    IL_0013:  ldloc.0
    IL_0014:  brfalse.s  IL_001c
    IL_0016:  ldloc.0
    IL_0017:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_001c:  endfinally
  }  // end handler 很奇怪,為什麼出現了try和finally結構呢? 按照這個思路,我重新寫了一段程式碼實現上面的功能. static void Main(string[] args)
  {
   A a = new A();
   try
   {
    Console.WriteLine(a.GetValue());
   }
   finally
   {
    a.Dispose();
   }
  } 再去用ildasm工具做反彙編,居然和使用using控制範圍結果獲得同樣的IL. 其實這樣也就可以結實為什麼必須實現Dispose介面的原因了,因為using範圍物件其實本質是對try..finally自動釋放的一種語法簡化.