關於C# using 作為定義範圍的問題
阿新 • • 發佈:2018-12-29
昨天我們團隊的一位同學問到我關於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自動釋放的一種語法簡化.
其實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自動釋放的一種語法簡化.