19 Oct 2021
C# 10 is being released in November 2021 along with .NET 6. There are several new language features being released. You can read about them here. The list has some interesting features, most of which are solutions to problems that I don't have.
The two (2) new features that excite me appeal directly to a desire to write less code, or at the very least, a chance to be more efficient with the code that I do wind up writing.
This language feature is a modifier that has been added to the existing
using
directive. You can read the official documentation for the
global modifier.
By applying this modifier to a using directive the directive will be
available in all files in the project. I like to think of this as an
#include
from the good ol' days. Just remember that the
global
directive must first and before your namespace
declaration.
This block of using
directives gets added to pretty much every
source file I am working on lately. Using this new feature I create a
Globals.cs
file and add it the project. I prefer this method to
the csproj
addition of the <Using />
element.
To me, it makes more sense to have a visible file, clearly named, rather than
relying upon developers to check the project file.
global using System; // for all files (if needed or not)
global using System.Collections.Generic; // obvious reasons
global using System.Linq; // makes playing with collections better
global using System.Threading.Tasks; // mostly for web projects
This method of including namespaces does not affect the .NET from removing assemblies when it is publishing a trimmed self-contained deployment.
This new feature is pure syntax gold. Why? I do not think I have ever created multiple namespaces within a single source file. I know it can be done, but it is not my normal convention: single namespace, single class per file. I have found that be a reasonable approach to organizing code. Of course, there are exceptions but never for multiple namespaces.
using System; // for all files (if needed or not)
using System.Collections.Generic; // obvious reasons
using System.Linq; // makes playing with collections better
using System.Threading.Tasks; // mostly for web projects
namespace TheNamespace
{
// Everything is now tabbed over - 4 spaces!
public class SampleClass { }
}
That is why the file-scoped namespace feature makes so much sense to me. It saves me code and give me back an entire level of indenting. When combined with global using directives the above code becomes:
namespace TheNamespace;
// Everything is now tabbed over - 4 spaces!
public class SampleClass { }
This works for me!
The reality is that these two (2) features are really just syntactic sugar. We currently get the same result by typing some extra characters. The compiler will still produce the same code. So why be lazy?
Frankly, I feel that file-scoped namespace is just being lazy ... for sure.
I will take it, however, because it is useful. The global using directives
saves time. If kept in a Globals.cs
or similar file it provides
a clear understanding of what to expect for the project. There is no digging
in the csproj
file. It can handle additions clearly and simply.
Once a team decides that is how they are going to manage their code, it
documents itself.
Updated: edited using block code to include global
to be more clear.