Simplify your C# code with `using` statement — Hugo Sum

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

Hugo Sum

A Hongkonger living in the UK. The only thing I know is there is so much I don't know.

Archive