當你在一個函數內使用一個可處理對象時,using語句是最簡單 的方法來保證這個對象被恰當的處理掉。當這些對象被分配時,會被編譯器放到 一個try/finally塊中。下面的兩段代碼編譯成的IL是一樣的:
SqlConnection myConnection = null;
(譯注:就我個人對 try/catch/finally塊的使用經驗而言,我覺得上面這樣的做法非常不方便。可 以保證資源得到釋放,卻無法發現錯誤。關於如何同時拋出異常又釋放資源的方 法可以參考一下其它相關資源,如Jeffrey的.Net框架程序設計,修訂版)
// Example Using clause:
using ( myConnection = new SqlConnection( connString ))
{
myConnection.Open();
}
// example Try / Catch block:
try {
myConnection = new SqlConnection( connString );
myConnection.Open();
}
finally {
myConnection.Dispose( );
}
如果你把一個不能處理類型的變量放置在using語句內,C#編譯器給出一個錯誤 ,例如:
// Does not compile:
// String is sealed, and does not support IDisposable.
using( string msg = "This is a message" )
Console.WriteLine( msg );
using只能在編譯時,那些支持IDispose接口的類型可以使用 ,並不是任意的對象:
// Does not compile.
// Object does not support IDisposable.
using ( object obj = Factory.CreateResource( ))
Console.WriteLine( obj.ToString( ));
如果obj實現了IDispose接口,那麼using語句就會生成資源 清理代碼,如果不是,using就退化成使用using(null),這是安全的,但沒有任 何作用。如果你對一個對象是否應該放在using語句中不是很確定,寧可為了更 安全:假設要這樣做,而且按前面的方法把它放到using語句中。
這裡講 了一個簡單的情況:無論何時,當你在某個方法內使用一個可處理對象時,把這 個對象放在using語句內。現在你學習一些更復雜的應用。還是前面那個例子裡 須要釋放的兩個對象:鏈接和命令。前面的例子告訴你創建了兩個不同的using 語句,一個包含一個可處理對象。每個using語句就生成了一個不同的 try/finally塊。等效的你寫了這樣的代碼:
public void ExecuteCommand( string connString,
string commandString )
{
SqlConnection myConnection = null;
SqlCommand MySQLCommand = null;
try
{
myConnection = new SqlConnection( connString );
try
{
MySQLCommand = new SqlCommand( commandString,
myConnection );
myConnection.Open();
MySQLCommand.ExecuteNonQuery();
}
finally
{
if ( MySQLCommand != null )
MySQLCommand.Dispose( );
}
}
finally
{
if ( myConnection != null )
myConnection.Dispose( );
}
}