c# - uso - tipos de variables en c++ y su significado
¿Qué hace una declaración de uso sin variable cuando se dispone? (4)
Siempre lo he usado usando con variable y asignación. Ahora tengo así una clase 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
}
Ahora estaba pensando en usarlo así:
using (DbProviderConnection cnctn = _planDb.CreateOpenConnection())
{
using (cnctn.BeginTransaction())
{
//...
cnctn.Transaction.Commit();
}
}
Mi pregunta es: ¿ DbProviderConnection.Transaction.Dispose
llama DbProviderConnection.Transaction.Dispose
?
De la especificación 8.13 de C # que usa la declaración definida como
using-statement:
using (resource-acquisition) embedded-statement
Donde la adquisición de recursos es
resource-acquisition:
local-variable-declaration
expression
En el primer caso tiene que usar el recurso que adquiere a través de la declaración de variable local. En segundo caso el recurso se adquiere a través de la expresión. Por lo tanto, en segundo caso, el resultado será el resultado de la llamada cnctn.BeginTransaction()
, que es DbTransaction
de su clase DbProviderConnection
. El uso de la declaración dispone su recurso después del uso. Entonces, sí, se DbProviderConnection.Transaction.Dispose()
.
ACTUALIZACIÓN: De acuerdo con el mismo artículo, su segundo bloque de uso se traducirá a
DbTransaction resource = cnctn.BeginTransaction();
try
{
//...
cnctn.Transaction.Commit();
}
finally
{
if (resource != null)
((IDisposable)resource).Dispose();
}
De la especificación:
8.13 La declaración de uso
Una declaración usando el formulario.
using (ResourceType resource = expression) statement
cuando ResourceType es un tipo de valor anulable o un tipo de referencia que no sea dinámico, la expansión es
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
Una declaración usando el formulario.
using (expression) statement
tiene las mismas tres posibles expansiones ... La variable de recurso es inaccesible e invisible para la declaración incrustada.
Por lo tanto, el objeto devuelto desde cnctn.BeginTransaction()
se eliminará cuando el bloque salga, pero no será accesible dentro del bloque asociado.
El objeto que devuelve BeginTransaction
es lo que se eliminará.
BeginTransaction devuelve un DbTransaction
modo que es lo que se eliminará
Sí, la disposición se llamará. La declaración de using
solo funciona con objetos desechables. Me gusta esto:
using (DbProviderConnection cnctn = _planDb.CreateOpenConnection())
{
using (cnctn.BeginTransaction())
{
// ...
cnctn.Transaction.Commit();
} // Here BeginTransaction.Dispose() is called.
} // Here DbProviderConnection.Dispose() is called.