.NET Tools
Essential productivity kit for .NET and game developers
File-Scoped Namespaces – A Look at New Language Features in C# 10
Welcome to the first part of our series, where we take a closer look at the new C# language features the .NET team has implemented, and how ReSharper and Rider make it easy to adopt them in your codebase. Welcome to C# 10 and .NET 6!
In this series, we are looking at:
- File-Scoped Namespaces
- Caller Argument Expressions
- Global Usings
- Improvements and Optimizations for Interpolated Strings
In this post we will talk about how to start using C# 10 in your projects and discuss file-scoped namespaces in depth. Have fun and be amazed!
How To Start Using C# 10
First of all, you will need the .NET 6.0 preview installed on your machine. Once installed, you can update the language version of your project. In Rider, we can do this from the Project Properties dialog:
Alternatively, you can hit Alt+Enter on any compiler error and execute the quick-fix:
Or manually update your project file as follows:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <LangVersion>preview</LangVersion> </PropertyGroup> </Project>
File-Scoped Namespaces
Most of you will probably confirm, that their C# files only contain a single namespace declaration:
namespace ConsoleApp { class Utilitiy { } // other types }
The new file-scoped namespaces allow you to declare them for the whole file and without using a block:
namespace ConsoleApp; class Utility { } // other types
This is truly a real-estate saver since you no longer have to apply a wasteful indentation to your whole type declarations in a file. If you’ve been using a custom Indent Size (usually 2 spaces) under Code Style | Tabs, Indents, Alignment or disabled the Indent inside namespace declaration setting under Code Style | Braces Layout, you can now come back to the language defaults.
ReSharper and Rider allow for a frictionless transition to file-scoped namespaces. From a single block-scoped namespace declaration, you can choose to switch styles for the file, project, or entire solution:
Remember: you can use git blame -w
to ignore whitespace changes from bulk formatting commits. Rider uses the switch by default for its Git Annotate action.
In order to achieve consistency, there is a new code style setting under Code Editing | C# | Syntax Style | Code Body to choose your preference and the violation severity. This is useful, for instance, when you converted your main branch but want to merge a branch that still uses block-scoped namespaces.
Remember: Code Styles are best saved to the team-shared settings layer.
If you have defined custom file templates, there is very good news: existing templates are file-scope ready. That means that ReSharper and Rider will convert the declaration automatically according to your code style settings. At the same time, when creating new templates with file-scoped namespaces, they are converted back to block-scoped when needed:
When we talk about file-scoped namespaces, some of you are probably reminded of package headers in Java and Kotlin. Unlike their counterpart, file-scoped namespaces in C# are not required to appear at the top of the file, meaning they are allowed to be preceded by using
directives. We expect most developers to prefer them right before type declarations, but you can configure this with the existing Add ‘using’ directive to deepest scope setting under the Code Style | Syntax Style options:
Download ReSharper 2021.3 EAP or check out Rider 2021.3 EAP to start taking advantage of C# 10 in the best possible way. We’d love to hear your thoughts!