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 the 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 projects when you have to maintain the code written ages ago.

What benefits we get with the new syntax? Less 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 that 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 important thing like what connection, stream or any other external resource stays opened, 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 reviewing.

Add comment