Top Level Programs in C# 9.0

02 juli 2021 om 10:00 by ParTech Media - Post a comment

In the present day world, almost all applications are following a modular approach. This simply means their components are segregated based on their functionalities. For example, if we take a web application, the front-end UI logic would have been developed and maintained separately from the back-end side.

With the advent of microservices, back-end web APIs have focus and control over only a single functionality. This opens up the need for the systems to be interconnected and pass information between them. Also, there will be instances where the back-end system will interact with a third-party system, send/retrieve data from them. There can even be external tools that can be accessed by the application for the processing of the request.

In all these cases, there is the possibility of getting errors or issues while trying to develop and establish connections between the APIs/third party systems/external tools. In such cases, debugging with the application in which it is being consumed will be tedious. The reason is simple - to call the other systems, the code has to satisfy the business flow and reach that point. This is not easy even for a simple system.

In such cases, developers create temporary stand-alone applications (mostly console applications - for its ease of access) and try to connect the other system from it. These applications are required to follow the standard coding practices in C# where the consumed packages are referred to in the using declarative statement and a class. Also, the Main method is required to start executing the code.

To make this debugging/proof of concept codes concentrate mainly on the functionality, C# has provided a wonderful feature called Top-level programs. It lets you concentrate directly on the functionality without the need to have headers, classes, and methods (Though they have been made optional).

Let's see in detail how to work on Top-level programs that come with C#.

Table of contents

  1. Introduction to top-level programs
  2. How to work with top-level programs?
  3. Conclusion

Introduction to top-level programs

Top-level programs are introduced as a part of C# version 9, which can be installed in your local machines either with Visual studio version 16.9 Preview 1 or with .NET 5 SDK.

As mentioned earlier, top-level programs help the developers to avoid the extra obligations by placing the program’s entry point in a static method of a class. Visual Studio typically supports one top-level program file per project.

A typical program.cs looks like below after creating a console application -

using System;

namespace PARTECH_TopLevel


​	class Program

​	{

​    static void Main(string[] args)

​    {

​      		Console.WriteLine("Hello World!");


​	}


How to work with top-level programs?

Note: If you are using a version of Visual Studio that is older than the one mentioned in the previous section, don’t forget to update it.

Step 1

To start with, create a console-based application and provide a valid name for the solution.

Step 2

Once you upgrade the Visual Studio, users might notice this new screen - Additional information. This is the section where we are going to choose the version of .NET that needs to be used in the project. As we saw earlier, top-level programs require .NET 5. So, we are going to create a console application project in .NET5.

Step 3

Open the program.cs file and look for the default set of lines (mentioned in the previous section) that are present in the file and remove all of them.

Step 4

Now let's try a small print statement in the program.cs using a top-level program. To achieve that, add the below lines -

System.Console.WriteLine("Hello World!");


This will generate a similar output as that of the default program (that you see upon creating a console application).

Step 5

Let's now see how to implement the concept of looping here using top-level programming. Add the following code -

for (var i = 0; i < 20; i++)

​	System.Console.WriteLine($"Number to print - {i}");



And the output prints numbers from 0 to 19 in the below order -

Number to print - 0

Number to print - 1

Number to print - 2

Number to print - 3

Number to print - 4



Number to print - 18

Number to print - 19

It is also possible to include delays or any functionalities that are being done through referencing.

for (var i = 0; i < 2; i++)


​	await System.Threading.Tasks.Task.Delay(1000);

​	System.Console.WriteLine($"Number to print - {i}");



The above code would wait for 1 second and execute the print statement.

It is also possible to write methods on the go and execute them in top-level programs. We will now wrap the above code inside a method and see how it can be done.


async void PrintSequence()


​	for (var i = 0; i < 2; i++)

​	{

  	await System.Threading.Tasks.Task.Delay(1000);

​    System.Console.WriteLine($"Number to print - {i}");

​	}

​	System.Console.ReadLine();


Here, the method call has been defined at the top, and the definition of the method follows it. This prints the same output (with a delay) as the previous step. Also, it is possible to refer to internal project libraries and call the required static methods inside the file. The best part is - you can also make HTTP client calls using top-level programs, through which you can debug the external calls.

using var httpClient = new System.Net.Http.HttpClient();

httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/plain"));

System.Console.WriteLine(httpClient.GetStringAsync(new System.Uri("[](")).Result);

If the same namespace reference is being used multiple times, then instead of adding the namespace at every instance it is used, you can add it as a using statement and continue with the top-level program approach.


Almost every year, Microsoft comes up with something which makes the developers life simpler Top-level programs is one such update that can help beginners to understand the code better. And once you get familiarized with it, you can dive deep and figure out how it is being converted and executed by the framework.