C# using statement

半城伤御伤魂 提交于 2019-12-05 05:16:23

using statement is just syntactic sugar and it gets translated into try/finally block. Starting with your code, here's how the C# compiler will translate the using block into 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, the resultTable gets disposed for sure regardless of the return statement. The using block only makes sure that object gets disposed after the scope.

Your first code looks ok to me and need not be changed.

Using does not catch exceptions, it just guarantees the .Dispose() call.

This is because,

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

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

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

However, if an exception is thrown, that exception will still prevent subsequent lines of code from being evaluated (with the exception of the .Dispose() which is always evaluated).

As such, if an exception occurs, your return will not return in either of your statements, but your DataTable will still be disposed.

If you want to guarantee a return occurs, even when 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;

The DataTable is disposed (.Dispose is called) in both cases.

It's translated into a try/finally, with Dispose being called in the finally. Finally, as the name implies, is called even when you call return.

In both your 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 The using statement) to find out the various scenarios (for reference types, non-nullable value types, and dynamic types).

Since DataTable is a reference type, your first sample 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();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!