[EPIC] .NET 6 C# project templates use latest language idioms
See original GitHub issueIn .NET 6, the included C# project templates will use the latest language idioms.
The following language features will be used or enabled by default in the SDK-included project templates as applicable:
- Top-level statements
- Global using directives (via SDK driven defaults)
- File-scoped namespaces (compiler tracking issue)
- Target-typed
new
expressions - Nullable reference types
- async Main
Issues
- #3360
- dotnet/test-templates#164
- dotnet/aspnetcore#33947
- dotnet/aspnetcore#33948
- dotnet/winforms#5171
- dotnet/wpf#4779
- dotnet/wpf#4774
- dotnet/maui#1497
- xamarin/xamarin-android#6076
- xamarin/xamarin-macios#12085
- dotnet/scaffolding#1594
- dotnet/efcore#25223
Area owners
Template area | Owner |
---|---|
Neutral (Console/Class lib) | @KathleenDollard |
Unit testing | @kendrahavens |
ASP.NET Core/gRPC/Worker | @DamianEdwards |
Blazor | @danroth27 |
WinForms | @OliaG |
WPF | @OliaG |
MAUI | @mhutch |
Implementation Considerations
- All changes detailed here will only be applied when the project is created targeting .NET 6+ (the default)
- Some templates have a
--langVersion
option and will need to condition the relevant changes based on the supplied value so that only compatible features are utilized in the new project - Making the changes opt-in is not being considered at this time as it defeats the intended purpose which is to have the default experience for new projects reflect the latest language idioms
- ❓ Should all changes detailed here have corresponding template options to allow opting-out of them at project creation time?
- ☑️ Decision on this is “No” for now. We can revisit based on feedback if necessary.
Top-level statements
- Language feature documentation
- Introduced in C# 9
- Project templates with an existing
Program.cs
will be updated to use top-level statements
Global using directives
- Language feature implementation issue
- Introduced in C# 10
- This feature is driven by SDK changes and as such no actual
global using
statements should appear in the template - Existing
using
statements in project templates that conflict with new SDK-driven default global using directives will be removed - The following namespaces are being globally included by the SDKs:
- Microsoft.NET.SDK:
- System
- System.Collections.Generic
- System.IO
- System.Linq
- System.Net.Http
- System.Threading
- System.Threading.Tasks
- Microsoft.NET.SDK.Web:
- Everything included by Microsoft.NET.SDK, plus:
- System.Net.Http.Json
- Microsoft.AspNetCore.Builder
- Microsoft.AspNetCore.Hosting
- Microsoft.AspNetCore.Http
- Microsoft.AspNetCore.Routing
- Microsoft.Extensions.Configuration
- Microsoft.Extensions.DependencyInjection
- Microsoft.Extensions.Hosting
- Microsoft.Extensions.Logging
- Microsoft.NET.SDK.Worker
- Everything included by Microsoft.NET.SDK, plus:
- Microsoft.Extensions.Configuration
- Microsoft.Extensions.DependencyInjection
- Microsoft.Extensions.Hosting
- Microsoft.Extensions.Logging
- Microsoft.NET.SDK:
File-scoped namespaces
- Language feature implementation issue
- Introduced in C# 10
- Any namespaces declared in existing project templates will be changed to use the file-scoped namespaces syntax
- ℹ️ This feature is not yet available in
main
builds but is expected to land during preview.7
Target-typed new
expressions
- Language feature documentation
- Introduced in C# 9
- Any constructor invocation where the type name can be omitted to reduce its duplication
- ✔️
private readonly static object s_syncObj = new object();
toprivate readonly static object s_syncObj = new();
- ❌
var someStrings = new List<string>();
stays as it is now as the type name is not repeated
- ✔️
Nullable reference types
- Language feature documentation
- Introduced in C# 8
- Existing project templates will enable the feature by default by having
<Nullable>enable</Nullable>
added to their.csproj
files- ℹ️ Enabling nullable reference types via SDK defaults was considered but rejected due to concerns with the experience during migration of existing projects to .NET 6, in that existing projects changed to target the .NET 6 TFM as part of migration will immediately exhibit compiler warnings associated with the feature being enabled and not handled correctly by the existing project code
.cs
,.cshtml
, and.razor
files in existing project templates will be updated to appropriately handle nullable reference types- Code generation tools (e.g. Scaffolding, EF Core Migrations, etc.) should also be updated to ensure they produce code that is aligned with the nullable configuration of the target project.
async Main
- Language feature documentation
- Introduced in C# 7.1
- Project templates with an existing
Program.cs
containing astatic void Main
method declaration with a body that includes calls toTask
-returning methods (or methods with aTask
-returning alternative) will be updated to declare the method asasync
and the calls toTask
-returning methods will be updated with theawait
keyword.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:23
- Comments:8 (4 by maintainers)
Top Results From Across the Web
C# language versioning - C# Guide
Learn about how the C# language version is determined based on your project and the reasons behind that choice. Learn how to override...
Read more >.NET 6 Preview 7: New Features Done, but Templates with ...
NET 6 has been powering key Microsoft properties -- Bing.com and ... Several templates were updated to leverage the latest language idioms.
Read more >What's New in Rider
Rider 2022.3 officially provides support for the .NET 7 SDK including: Updated project templates. NuGet Central Package Management. Support for ASP.NET minimal ...
Read more >Unreal Engine 5.2 Release Notes
Overview of new and updated features in Unreal Engine 5.2. ... Fixed 6-image array DDS files being imported as cube maps. Fixed Advanced...
Read more >The Complete Glossary of Project Management Terms
The ultimate resource for project management terminology. Get easy-to-understand explanations of all key concepts to make sure you use the ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
These template changes do need opt-out options that don’t involve “copy the old template and start from there” as the docs at https://aka.ms/new-console-template suggest. Toggles on project creation wouldn’t be a full solution as added classes will have no way to derive which template to use, given that this is mostly preference driven, code style options seem like the most logical choice.
I’ll start with the disclaimer that I sadly cannot perform a full evaluation of these changes as my VS2022 installation appears to be broken (projects won’t load at all within solutions, so other than the default Program.cs, Class1.cs or manually selected files opening without language features, I can’t see how it all works in practice), but I do have strong feelings towards these changes.
I’m all in for new features such as
async Main
being used by default templates (at least the option to choose entry point type to save the couple of seconds it takes to rewrite theMain
signature and referenceSystem.Threading.Tasks
), however, oversimplification by removing or changing using directives, namespace and class definitions by default with features such as “top-level statements” and “file-scoped namespaces” (as done for the Console and Library templates) for anyone other than beginners would likely be nothing but a cumbersome and potentially confusing change. These changes DO affect readability, and I’d argue that’s not for the better, these changes make it so you can no longer tell exactly what your program is doing at a glance without learning the implicit using directives and default entry point signature for your targeted runtime, which if changed in any future revision, can potentially affect the results of existing code based on the new template.There’s also the matter of code style consistency and preferences, as for consistency l fear this would be conflicting with existing projects and solutions that are upgraded to .NET 6 and new classes/projects are added (sadly I cannot test this at the moment), as for preferences, I (and others may) prefer explicit type definitions over
var
, for similar reasons I would prefer explicit using directives, I would also prefer the old style of namespace definitions given my brace and spacing preferences.Closing this as work in .NET 6 has been completed. A couple of items were pushed to post-6.0.