Joydip Kanjilal
Contributor

How to use top-level programs in C# 9

how-to
Mar 23, 20215 mins
C#Microsoft .NETSoftware Development

Take advantage of the new top-level statements in C# 9.0 to eliminate boilerplate code and make your programs more readable, maintainable, and efficient.

rock stacking
Credit: SwissMediaVision / Getty Images

When writing programs in the C# programming language, you invariably need to write a lot of boilerplate code — even for simple console applications. Imagine that you want to write some code to test whether a library or an API is functioning properly. You might write a console application to accomplish this, but you’re nonetheless constrained to follow standard C# semantics. You must write your code inside the Main method.

Top-level programs, a new concept introduced in C# 9.0, allow you to write code for simple programs sans the need to write boilerplate code. Top-level programs are a great new feature that allows you to write cleaner, shorter, and simpler code. You can take advantage of top-level programs to explore new ideas. This article discusses how you can work with top-level programs in C# 9.0.

To work with the code examples provided in this article, you should have Visual Studio 2019 installed in your system. If you don’t already have a copy, you can download Visual Studio 2019 here. Note that C# 9.0 is available in Visual Studio 2019 version 16.9 Preview 1 or later, and in the .NET 5.0 SDK.

Create a .NET Core console application project in Visual Studio

First off, let’s create a .NET Core console application project in Visual Studio. Assuming Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new .NET Core console application project in Visual Studio.

  1. Launch the Visual Studio IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “Console App (.NET Core)” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Click Create.

We’ll use this project to work with top-level programs in the subsequent sections of this article.

Top-level program example in C# 9.0

Let’s look at a before-and-after example of how top-level programs can eliminate boilerplate code. Before top-level statements in C# 9.0, this is the minimal code you’d write for a console application:

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

When working with C# 9.0, we can avoid the noise and take advantage of top-level programs to write our code in a much simpler way. The following code snippet illustrates how you can take advantage of top-level statements to refactor the above code:

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

In either case, when the program is executed, you’ll see the string “Hello World!” displayed at the console window.

Use methods in top-level programs in C# 9.0

You can use methods with top-level programs. Below is a code example that illustrates how you can use methods with top-level programs.

System.Console.WriteLine(DisplayMessage("Joydip!"));
System.Console.Read();
static string DisplayMessage(string name)
{
    return "Hello, " + name;
}

When you execute the above program, you should see the output “Hello, Joydip!” appear in the console window:

Use classes in top-level programs in C# 9.0

You can also use classes, structs, and enums in top-level programs. The following code snippet illustrates how you can use classes in top-level programs.

System.Console.WriteLine(new Author().DisplayMessage("Joydip!"));
System.Console.Read();
public class Author
{
    public string DisplayMessage(string name)
    {
        return "Hello, " + name;
    }
}

When you execute the above program, the output will be similar to Figure 1.

How top-level programs work in C# 9.0

So, how do top-level programs work exactly? What happens behind the scenes? Top-level programs are essentially a compiler feature. If you don’t write the boilerplate code, the compiler will generate it for you.

Refer to the following piece code we wrote earlier.

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

The code displayed below (generated using the SharpLab online tool) shows what the compiler-generated code would look like.

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[CompilerGenerated]
internal static class <Program>$
{
    private static void <Main>$(string[] args)
    {
        Console.WriteLine("Hello World!");
    }
}

If you look at the compiler-generated code, you’ll see the [CompilerGenerated] attribute on top of the static class generated by the compiler.

Top-level programs are a great new feature in C# 9.0, whereby the compiler automatically generates the boilerplate code for you behind the scenes. Top-level programs are great for simple programs that don’t have too many files and dependencies. Note that only one file in your application may use top-level statements; otherwise the compiler throws an error.

One downside to top-level programs is that, if you’re new to C#, you might not be able to understand what’s happening in the code behind the scenes. A better way for beginners to learn C# will be using the Main method, and avoiding top-level statements until you understand how the Main method works. But those who have mastered Main will find top-level statements a very useful shortcut.

Joydip Kanjilal
Contributor

Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net.

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference, which is held twice each year.

More from this author