Console Application difference between .NET Core 3.1 and .NET 6.0

3 minute read

In this previous post, I’ve explore on the default project templates when .NET 6.0 SDK is installed only and not through Visual Studio 2022. In this post, let’s do a simple deep dive into .NET 6.0 console application and compare it with .NET Core 3.1.

How about .NET 5.0? Since .NET 5.0 doesn’t offer LTS before, I simply chose to skip it and focus more on .NET release with LTS support. Also, I’ll be using VS Code with DEV containers for both .NET Core 3.1 and .NET 6.0. Lets get started…

Console Project Initialization

Running dotnet new console for both .NET Core 3.1 and .NET 6.0 are identical in terms on the number of files that is being generated from the template. Below is the list of files and folder:

  • .csproj file - C# Project file
  • Program.cs - the main program file
  • obj folder - which contains some nuget configuration and it’s project assets

Changes on the csproj file.

There is a new tag <ImplicitUsings /> which is enable by default. When enable you don’t need to add using System in the cs files. What this means for each code file, it doesn’t need to add the using System, it will be available to all code files within the project. Each project templates (i.e. webapi, console) has its own default set of namespaces that are implicitly define. More details can be found here.

Changes on the Program.cs file

In .NET 6.0 Console Project Template it uses top-level statement feature, what this mean you write directly the code without the main method. The compiler take cares of it during compilation. It only allows one code file to use top-level statement feature. Having two or more codes file with top-level statement feature, would cause an error during compilation. See post here, to learn about more on top-level statements. Below is an illustration on having 2 code files with top-level statements.

multi-toplevel-statements

Building the project

Although both would output the same result **Hello, World!”, there are several difference things when building the project. Once dotnet build is run, the obj and bin folders are generated. Let’s take a look first on obj/Debug/net6.0 folder, in .NET 6.0 below are the new files that are not found in .NET Core 3.1:

  • ref and refint folder
  • .globalusings.cs file
  • .GeneratedMSBuildEditorConfig.editorconfig file

Let’s focus on the .globalusings.cs file, below is the content of the file

// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;

Since the .NET 6.0 Implict Usings feature is enabled by default, for console application the above are the preset namespaces that will be global. Below is a sample illustration to show the .globalusings.cs file is generated by default. Implicit Usings Enabled

By disabling the Implicit Usings in the .csproj file and building the project again, this file wouldn ‘t be generated. See illustration below. Implicit Usings Disabled

Takeaways

  • With Implicit Usings enabled, there is no need to add Using statements on the top each code file in the project because they are globally available. However, some would still prefer the old style of having Using statements on the code file to see it in once glance that what are the namespaces that are being used in the code file. So it is a matter of preference on the team either to adopt this new feature, or prefer the old style or a mix of both. My preference would be a mix of both, for common namespaces like what it have in preset on console applicaion.

  • Top-level statements are useful for writing simple or micro code that run a specific task, testing out an algorithm/logic or even a function app.