Does a C# using statement perform try/finally?
Suppose that I have the following code:
private void UpdateDB(QuoteDataSet dataSet, Strint tableName)
{
using(SQLiteConnection conn = new SQLiteConnection(_connectionString))
{
conn.Open();
using (SQLiteTransaction transaction = conn.BeginTransaction())
{
using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM " + tableName, conn))
{
using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter())
{
sqliteAdapter.Update(dataSet, tableName);
}
}
transaction.Commit();
}
}
}
The C# doc开发者_StackOverflow社区umentation states that with a using
statement the object within the scope will be disposed and I've seen several places where it's suggested that we don't need to use try/finally clause.
I usually surround my connections with a try/finally, and I always close the connection in the finally clause. Given the above code, is it reasonable to assume that the connection will be closed if there is an exception?
You are correct; the using
statement compiles to a try
/ finally
block.
The compiler transforms using(resource) statement;
into the following code:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
(The cast to IDisposable
is in case ResourceType
implements IDisposable
explicitly.
Yes, you either need to use a try/finally or a using statement. You don't need both.
A using statement is almost the same as a try/finally except that in C# 3 you can't reassign to the variable inside the using block.
using (IDisposable d = foo())
{
d = null; // Error: Cannot assign to 'd' because it is a 'using variable'
}
Previously you could reassign but the original object would still be disposed, not the newly assigned object and you would also get this compile warning:
Possibly incorrect assignment to local 'd' which is the argument to a using or lock statement. The Dispose call or unlocking will happen on the original value of the local.
Yes, the using
statement is pretty much just shorthand for a try ... finally
block.
For example, this code...
using (MyDisposableType foo = new MyDisposableType())
{
foo.DoSomething();
}
...would equate to the following...
{
MyDisposableType foo = new MyDisposableType();
try
{
foo.DoSomething();
}
finally
{
if (foo != null)
((IDisposable)foo).Dispose();
}
}
You can assume that the connection will be closed if you get an exception.
Using() ensures that the item instantiated within the parameters will be disposed of regardless of that happens within the associated code block. This includes closing the database connection assuming that SQLiteConnection
handles its disposal correctly.
精彩评论