The new using declaration in C# 8
C# 8 contains a new "enhancement" to the syntax: a declaration of using scope as a variable. While it might be considered as a good simplification to one of the most used constructions, not everything is so univocal.
Let's take a look at the code as you would write it using the current live version of C#:
public async Task Save(Document document)
{
using (var context = new DocDbContext())
{
context.Documents.Add(document);
await context.SaveChangesAsync();
}
}
Everything is quite simple: the method creates a context to access the DB, adds some entity, and saves the changes.
In C# 8 there is a new syntax-sugar: if there is nothing else after the using
scope, it is possible to reduce nesting and declare using
as a variable:
public async Task Save(Document document)
{
using var context = new DocDbContext();
context.Documents.Add(document);
await context.SaveChangesAsync();
}
If we do something after the using
, compiler complains about such syntax. However, it is possible to keep the code before the using
block.
Additionally, it is not possible to reassign the variable created in such way or push it as an out
parameter.
While it looks nice and simplifies a code, in my opinion, developers might make more mistakes in methods with such syntax inside, especially in a long-living project when you have to maintain the code written ages ago.
What benefits do we get with the new syntax? Fewer brackets and less nesting. A little bit. And only several cases where it can be applied. In return, it becomes less obvious what is the scope of an entity should be disposed.
Later a developer might add some additional stuff to the code, missing the fact where actually the added code will appear after compilation.
Such an important thing like what connection, stream, or any other external resource stays open, and where and when should be disposed, becomes hidden.
Generally, such kind of syntax makes code less maintainable, and it requires more attention during the development and review.