Simplify your C# code with using statement
As someone who started coding with Javascript and now mainly working with C#, my transition was smooth as these two languages are relatively similar syntax wise. As I read more and more C# code written by my colleagues, I realised how concise my code can be using the using statement.
In this post I will share what is using statement, when can you use it and its limitation.
What is a using statement and when can you use it
The using statement is a feature introduced since C# 8.0, and it can only be used with objects that implemented System.IDisposable or System.IAsyncDisposable. It is a syntactical sugar that will be transformed to a try...finally statement during compile time, and StreamReader.Dispose method will be automatically called in the finally block.
Considering an example of creating a connection with a SQL database and executing SELECT GETDATE(), using the try...finally statement.
SqlConnection conn = null;
try
{
conn = new SqlConnection("Server=whatever;Database=whatever;User Id=whatever;Password=whatever;");
await conn.OpenAsync();
SqlCommand command = new SqlCommand("SELECT GETDATE()", conn);
object result = command.ExecuteScalar();
}
finally
{
if (conn != null)
{
await conn?.CloseAsync(); // close connection so we don't occupy all of them in the pool
}
}If we rewrite that with the using statement, the finally block is now hidden from us. Also we don’t have to declare a variable outside the scope of try...finally block, and reassign the variable. Our code is now clean and concise.
using(var conn = new SqlConnection("Server=whatever;Database=whatever;User Id=whatever;Password=whatever;")){
await conn.OpenAsync();
SqlCommand command = new SqlCommand("SELECT GETDATE()", conn);
object result = command.ExecuteScalar();
}Handling exception with the using statement
You might ask where is the catch? Since using statement is only a syntactical sugar for try...finally, it does not catch exception for you. To catch exception, you will have to put using statement inside try...catch.
try
{
using(SqlConnection conn = new SqlConnection(connString))
{
// interact with the connection, omitted for brevity
}
}
catch (Exception exc)
{
// handle exception
}I have also seen people putting try...catch inside using too, but I would not recommend this(unless you want to lay mines for your team). Since the try...catch is now inside the scope of using, exceptions of SqlConnection conn = new SqlConnection(connString) are not caught. You have to make sure that line would not throw exception if you write it this way.
using(SqlConnection conn = new SqlConnection(connString))
{
try
{
// interact with the connection, omitted for brevity
}
catch (Exception exc)
{
// handle exception
}
}