2010-07-06 52 views
7

我真的想從我的腦海中解脫出來。請參閱下面的代碼:C#使用語句

using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) { 
    List<string> resultsList = new List<string>(); 
    foreach (DataRow dataRow in resultTable.Rows) { 
     resultsList.Add(dataRow[0].ToString()); 
    } 
    return resultsList; 
} 

數據表是否被丟棄?有人可以解釋這是如何翻譯成try/catch/finally塊的嗎? MSDN指出,如果發生異常,Dispose方法仍然會被調用,但是return語句呢?

或者我應該使用下面的代碼:

List<string> resultsList = new List<string>(); 
using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) { 
    foreach (DataRow dataRow in resultTable.Rows) { 
     resultsList.Add(dataRow[0].ToString()); 
    } 
} 
return resultsList; 

可能,第二個應該被使用,但我只需要啓蒙:)。請解釋。謝謝。

+1

把你的回報,無論你想,在處置將被稱爲無關。 '使用'是你的朋友! – Chris 2010-07-06 04:29:30

回答

5

using說法只是語法糖,它被翻譯成try/finally塊。從您的代碼開始,下面是C#編譯器如何將using塊轉換爲try/finally塊。

 try 
     { 
      DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable"); 
      List<string> resultsList = new List<string>(); 
      foreach (DataRow dataRow in resultTable.Rows) 
      { 
       resultsList.Add(dataRow[0].ToString()); 
      } 
      return resultsList; 
     } 
     finally 
     { 
      resultTable.Dispose(); 
     } 

正如您從代碼中看到的那樣,不管return語句如何,resultTable都會被處理。使用塊只能確保對象在範圍之後被處理。

你的第一個代碼看起來對我而言並不需要改變。

1

在這兩種情況下都會處理DataTable(調用.Dispose)。

它被翻譯成try/finally,在finally中調用Dispose。最後,顧名思義,即使您致電return,也會被稱爲。

4

Using捕獲異常,它只是保證了.Dispose()電話。

這是因爲,

using (ResourceType resource = new ResourceType())等同於:

ResourceType resource; 
try 
{ 
    resource = new ResourceType(); 
    /* The insides of the using block */ 
} 
finally 
{ 
    resource.Dispose(); 
} 

.Dispose()通話將總是進行評估。如果您在using區塊內返回(在「真正」返回之前),則會調用Dispose呼叫。如果拋出異常,甚至會評估Dispose調用。

然而,如果將引發異常,該異常會仍然防止後續代碼行從被評估(帶有.Dispose()除外,它是總是評價)。

因此,如果發生異常,您的return將不會返回您的任何一項聲明中,但您的DataTable仍將被處置。

如果你想保證收益發生,即使在發生錯誤時,你想要做這樣的事情:

List resultsList = new List(); 
try 
{ 
    using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) 
    { 
     foreach (DataRow dataRow in resultTable.Rows) 
     { 
      resultsList.Add(dataRow[0].ToString()); 
     } 
    } 
} 
catch 
{ 
} 
return resultsList; 
1

在這兩個例子中,將調用Dispose。這是因爲using語句擴展爲try/finally塊。

去閱讀C# Language Specification(8.13使用語句)來找出各種情況(對於引用類型,非空值類型和動態類型)。

由於DataTable是引用類型,第一個樣品將擴大到以下幾點:

{ 
    DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable"); 
    try { 
     List<string> resultsList = new List<string>(); 
     foreach (DataRow dataRow in resultTable.Rows) { 
      resultsList.Add(dataRow[0].ToString()); 
     } 
     return resultsList; 
    } 
    finally { 
     if (resultTable != null) ((IDisposable)resultTable).Dispose(); 
    } 
}