Ámbito local implícito en sentencias using de C# 8 - Code Variables -->
Code Variables Code Variables

Latest news

جاري التحميل ...

Ámbito local implícito en sentencias using de C# 8

.NET CoreLa palabra clave using, utilizada tanto en forma de directiva como de instrucción, es una de las más sobrecargadas del lenguaje C#. Es útil para bastantes cosas, como la importación de espacios de nombres, definición de alias de namespaces o tipos, simplificar el acceso a miembros de tipos estáticos, o para especificar bloques o ámbitos de uso de recursos (objetos IDisposable) que deben ser liberados automáticamente.

Centrándonos en este último caso de uso, seguro que en muchas ocasiones habéis escrito código como el siguiente, donde vamos anidando objetos IDisposable para asegurar que al finalizar la ejecución de cada bloque los recursos sean liberados de forma automática:
void DoSomething()
{
using(var conn = new SqlConnection(...))
{
connection.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "...";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// ...
}
}
}
}
}
Al final, lo que encontramos es código con un nivel de indentación muy alto, y que resulta muy extenso, básicamente porque una gran parte de las líneas las dedicamos sólo a abrir y cerrar llaves. A la postre, esto sólo hace que nuestro código crezca a lo ancho, lo cual no es bueno desde el punto de vista de la simplicidad y facilidad de lectura.

Pues bien, C# 8 introduce una pequeña mejora destinada a simplificar la codificación de este tipo de ámbitos de uso de recursos: el ámbito local implícito. A partir de esta versión del lenguaje, podremos escribir un código como el anterior de la siguiente manera:
void DoSomething()
{
using var conn = new SqlConnection(...);
connection.Open();

using var cmd = conn.CreateCommand();
cmd.CommandText = "...";

using var reader = cmd.ExecuteReader();
while (reader.Read())
{
// ...
}
}
Utilizando la construcción using var ... que vemos en el código anterior, estamos indicando al compilador que la liberación del recurso declarado debe realizarse de forma automática cuando finalice el ámbito en el que nos encontramos. En el ejemplo anterior, la llamada al método Dispose() se realizará al finalizar la ejecución de `DoSomething()'.
Recuerda que a día de hoy ya puedes probar C# 8 en Visual Studio 2019 o directamente desde la interfaz de línea de comandos de .NET Core.
Por supuesto, esto aplica a cualquier tipo de ámbito, por lo que podríamos utilizar esta sintaxis en cualquier tipo de bloque, como un if u otros de los permitidos por el lenguaje:
if (expr)
{
using var fileStream = File.Create(...);
...
// Aquí se liberará fileStream automáticamente
}
Como detalle de implementación, pero que tiene su sentido, la liberación se realizará en orden inverso a como han sido declarados, de forma que el resultado sería muy similar a si hubiéramos optado por utilizar bloques using tradicionales.

Mmmm... no sé, no sé....

La verdad es que tengo sensaciones raras respecto a esta novedad del lenguaje. Por una parte es cierto que todo lo que nos ahorre teclear más es una ventaja y que evitar la verbosidad hace que todo sea más simple. Desde este punto de vista, la idea me convence :)

Sin embargo, el hecho de eliminar los bloques explícitos hace menos visible la intención de liberar los recursos utilizados... y sobre todo, no sé si podría hacer más difícil detectar cuándo se nos ha olvidado hacerlo.

Por ejemplo, echando un vistazo al código siguiente, no es fácil detectar que se nos olvidó añadir el using en una de las declaraciones:
void DoSomething()
{
using var conn = new SqlConnection(...);
connection.Open();

var cmd = conn.CreateCommand();
cmd.CommandText = "...";

using var reader = cmd.ExecuteReader();
while (reader.Read())
{
// ...
}
... // Aquí se liberarán conn, cmd y reader... ¿o no?
}
También, aunque entiendo que la excesiva indentación que podría darse por la utilización de bloques using convencionales puede ser perjudicial para facilitar la comprensión y legibilidad de el código, es fácilmente salvable extrayendo bloques a métodos, funciones locales o incluso otros componentes. Incluso en muchos casos estaríamos diseñando mejor nuestros componentes en términos de aplicación de niveles de abstracción correctos en cada lugar.

En fin, supongo que iré teniendo una opinión más formada cuando empiece a ver la utilización que le damos a esta característica y los problemas o beneficios que nos vaya trayendo su uso :)

Publicado en Variable not found.

Comments



If you like the content of our blog, we hope to stay in constant communication, just enter your email to subscribe to the blog's express mail to receive new blog updates, and you can send a message by clicking on the button next ...

إتصل بنا

About the site

author Code Variables  Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

Learn more ←

Blog visitors

Blog stats

All Copyrights Reserved

Code Variables

2019