C # using operator

I really want to get this out of my head. See below code:

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; } 

Is data placement? Can someone explain how this translates to a try / catch / finally block? MSDN states that if an exception occurs, the Dispose method will still be called, but what about the return statement?

Or just I have to use the code below:

 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; 

Maybe you need to use the second, but I just need enlightenment :). Please explain. Thanks.

+7
c # using-statement using
source share
4 answers

using statement is just syntactic sugar and it is converted to a try / finally block. Starting with your code, here is how the C # compiler translates the using block into a try / finally block.

  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(); } 

As you can see from the code, resultTable gains confidence regardless of the return statement. The used block only ensures that the object will be deleted after the area.

Your first code looks fine to me and doesn't need to be changed.

+5
source share

Using does not throw an exception; it just guarantees a call to .Dispose() .

It's because

using (ResourceType resource = new ResourceType()) equivalent to:

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

A call to .Dispose() will always be evaluated. The Dispose call is even evaluated if you return to your Using block (before it "really" returns). A Dispose call is even evaluated if an exception is thrown.

However, if an exception is thrown, that exception will still prevent the evaluation of subsequent lines of code (except for .Dispose() , which is always evaluated).

Thus, if an exception occurs, your return will not be returned in any of your statements, but your DataTable will still be deleted.

If you want to guarantee a return, even if an error occurs, you want to do something like this:

 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; 
+4
source share

In both cases, a DataTable ( .Dispose ) is located.

It translates to try/finally , with Dispose called in finally . Finally, as the name suggests, is called even when return called.

+1
source share

In both examples, Dispose will be called. This is because the using statement expands to a try / finally block.

Go read the C # Language Specification (8.13 using statement) to find out different scenarios (for reference types, a value not equal to nullable types and dynamic types).

Since a DataTable is a reference type, your first pattern will expand to the following:

 { 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(); } } 
+1
source share

All Articles