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
}
}