Предположим, что у меня есть следующий код:
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();
}
}
}
Документация C# указывает это с a using
оператор объект в объеме будет расположен и я видел несколько мест, где предложено, чтобы мы не должны были использовать пункт попытки/наконец.
Я обычно окружаю свои соединения попыткой/наконец, и я всегда окружаю соединение наконец пункт. Данный вышеупомянутый код, действительно ли разумно предположить, что соединение будет закрыто, если будет исключение?
Вы правы; оператор using
компилируется в блок try
/ наконец
.
Компилятор преобразует using(resource);
в следующем коде:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
(Приведение в IDisposable
в случае, если ResourceType
реализует IDisposable
явно.
Использование () гарантирует, что элемент, созданный в параметрах, будет удален независимо от того, что происходит в соответствующем блоке кода. Это включает в себя закрытие соединения с базой данных при условии, что SQLiteConnection
правильно обрабатывает его удаление.
Вы можете предположить, что соединение будет закрыто, если вы получите исключение.
Да, оператор using
в значительной степени является сокращением для блока try ... finally
.
Например, этот код ...
using (MyDisposableType foo = new MyDisposableType())
{
foo.DoSomething();
}
... будет соответствовать следующему ...
{
MyDisposableType foo = new MyDisposableType();
try
{
foo.DoSomething();
}
finally
{
if (foo != null)
((IDisposable)foo).Dispose();
}
}
Да, вам нужно либо использовать команду try / finally, либо оператор using. Вам не нужны оба.
Оператор using почти такой же, как try / finally, за исключением того, что в C # 3 нельзя переназначить переменную внутри блока using.
using (IDisposable d = foo())
{
d = null; // Error: Cannot assign to 'd' because it is a 'using variable'
}
Раньше вы могли переназначить, но исходный объект все равно будет удален, а не вновь назначенный объект, и вы также получите это предупреждение компиляции:
Возможно неправильное присвоение локальному 'd', которое является аргументом для использования или блокировки утверждение. Вызов Dispose или разблокировка произойдет на исходном значении локального.