Что делает использование инструкции без переменной при утилизации?
Я всегда использовал использование с переменной и присваиванием. Теперь у меня есть класс DbProviderConnection класса:
public class DbProviderConnection : IDisposable
{
public DbConnection Connection { get; set; }
public DbTransaction Transaction { get; set; }
public DbTransaction BeginTransaction()
{
Transaction = Connection.BeginTransaction();
return Transaction;
}
//... and so on
}
Теперь я подумал, чтобы использовать его вот так:
using (DbProviderConnection cnctn = _planDb.CreateOpenConnection())
{
using (cnctn.BeginTransaction())
{
//...
cnctn.Transaction.Commit();
}
}
Мой вопрос: вызывается ли DbProviderConnection.Transaction.Dispose
?
Ответы
Ответ 1
Из С# Specification 8.13 с использованием оператора, определенного как
using-statement:
using (resource-acquisition) embedded-statement
Если получение ресурсов
resource-acquisition:
local-variable-declaration
expression
В первом случае вы используете, который приобретает ресурс через объявление локальной переменной. Во втором случае ресурс приобретается через выражение. Итак, во втором случае resouce будет результатом вызова cnctn.BeginTransaction()
, который DbTransaction
из вашего класса DbProviderConnection
. Использование выражения предоставляет свой ресурс после использования. Итак, да, DbProviderConnection.Transaction.Dispose()
будет вызван.
ОБНОВЛЕНИЕ: согласно той же статье ваш второй блок использования будет переведен на
DbTransaction resource = cnctn.BeginTransaction();
try
{
//...
cnctn.Transaction.Commit();
}
finally
{
if (resource != null)
((IDisposable)resource).Dispose();
}
Ответ 2
Да, Dispose будет вызван. Оператор tTe using
работает только с одноразовыми объектами. Вот так:
using (DbProviderConnection cnctn = _planDb.CreateOpenConnection())
{
using (cnctn.BeginTransaction())
{
//...
cnctn.Transaction.Commit();
} //HERE THE BEGIN TRANSACTION DISPOSE() METHOD IS BE CALLED.
}//HERE THE DbProviderConnection DISPOSE() METHOD IS BE CALLED.
Ответ 3
Из спецификации:
8.13 Оператор using
A, используя инструкцию вида
using (ResourceType resource = expression) statement
когда ResourceType является типом значения NULL или ссылочным типом, отличным от динамического, расширение
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
A, используя инструкцию вида
using (expression) statement
имеет те же три возможных разложения... Переменная ресурса недоступна и невидима для встроенного оператора.
Поэтому объект, возвращенный из cnctn.BeginTransaction()
, будет удален, когда блок выйдет, но недоступен внутри соответствующего блока.
Ответ 4
Объект, возвращаемый BeginTransaction
, является тем, что будет удалено.
BeginTransaction возвращает DbTransaction
, так что это будет размещено