C# console app template generates top-level statements

Starting with .NET 6, the project template for new C# console apps generates the following code in the Program.cs file:

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

The new output uses recent C# features that simplify the code you need to write for a program. For .NET 5 and earlier versions, the console app template generates the following code:

using System;

namespace MyApp // Note: actual namespace depends on the project name.
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

These two forms represent the same program. Both are valid with C# 10.0. When you use the newer version, you only need to write the body of the Main method. The compiler synthesizes a Program class with a Main method and places all your top level statements in that Main method. You don't need to include the other program elements, the compiler generates them for you. You can learn more about the code the compiler generates when you use top level statements in the article on top level statements in the C# Guide's fundamentals section.

You have two options to work with tutorials that haven't been updated to use .NET 6+ templates:

  • Use the new program style, adding new top-level statements as you add features.
  • Convert the new program style to the older style, with a Program class and a Main method.

If you want to use the old templates, see Use the old program style later in this article.

Use the new program style

The features that make the new program simpler are top-level statements, global using directives, and implicit using directives.

The term top-level statements means the compiler generates the class and method elements for your main program. The compiler generated class and Main method are declared in the global namespace. You can look at the code for the new application and imagine that it contains the statements inside the Main method generated by earlier templates, but in the global namespace.

You can add more statements to the program, just like you can add more statements to your Main method in the traditional style. You can access args (command-line arguments), use await, and set the exit code. You can even add functions. They're created as local functions nested inside the generated Main method. Local functions can't include any access modifiers (for example, public or protected).

Both top-level statements and implicit using directives simplify the code that makes up your application. To follow an existing tutorial, add any new statements to the Program.cs file generated by the template. You can imagine that the statements you write are between the open and closing braces in the Main method in the instructions of the tutorial.

If you'd prefer to use the older format, you can copy the code from the second example in this article, and continue the tutorial as before.

You can learn more about top-level statements in the tutorial exploration on top-level statements.

Implicit using directives

The term implicit using directives means the compiler automatically adds a set of using directives based on the project type. For console applications, the following directives are implicitly included in the application:

  • using System;
  • using System.IO;
  • using System.Collections.Generic;
  • using System.Linq;
  • using System.Net.Http;
  • using System.Threading;
  • using System.Threading.Tasks;

Other application types include more namespaces that are common for those application types.

If you need using directives that aren't implicitly included, you can add them to the .cs file that contains top-level statements or to other .cs files. For using directives that you need in all of the .cs files in an application, use global using directives.

Disable implicit using directives

If you want to remove this behavior and manually control all namespaces in your project, add <ImplicitUsings>disable</ImplicitUsings> to your project file in the <PropertyGroup> element, as shown in the following example:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    ...
    <ImplicitUsings>disable</ImplicitUsings>
  </PropertyGroup>

</Project>

Global using directives

A global using directive imports a namespace for your whole application instead of a single file. These global directives can be added either by adding a <Using> item to the project file, or by adding the global using directive to a code file.

You can also add a <Using> item with a Remove attribute to your project file to remove a specific implicit using directive. For example, if the implicit using directives feature is turned on with <ImplicitUsings>enable</ImplicitUsings>, adding the following <Using> item removes the System.Net.Http namespace from those that are implicitly imported:

<ItemGroup>
  <Using Remove="System.Net.Http" />
</ItemGroup>

Use the old program style

Starting with .NET SDK 6.0.300, the console template has a --use-program-main option. Use it to create a console project that doesn't use top-level statements and has a Main method.

dotnet new console --use-program-main

The generated Program.cs is as follows:

namespace MyProject;
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");
    }
}

Use the old program style in Visual Studio

  1. When you create a new project, the setup steps will navigate to the Additional information setup page. On this page, select the Do not use top-level statements check box.

    Visual Studio do not use top-level statements check box

  2. After your project is created, the Program.cs content is as follows:

    namespace MyProject;
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
    

Note

Visual Studio preserves the value for the options next time you create the project based on the same template, so by default when creating Console App project next time the "Do not use top-level statements" check box will be checked. The content of the Program.cs file might be different to match the code style defined in the global Visual Studio text editor settings or the EditorConfig file.

For more information, see Create portable, custom editor settings with EditorConfig and Options, Text Editor, C#, Advanced.

Template feedback

Top-level statements was introduced in .NET 6. Add an up or down vote in GitHub issue #27420 to let us know if you support the use of this feature in project templates.