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. 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. Launch the Visual Studio IDE. Click on “Create new project.” In the “Create new project” window, select “Console App (.NET Core)” from the list of templates displayed. Click Next. In the “Configure your new project” window, specify the name and location for the new project. 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. How to do more in C#: How to use pattern matching in C# How to work with read-only collections in C# How to work with static anonymous functions in C# 9 How to work with record types in C# How to use implicit and explicit operators in C# Singleton vs. static classes in C# How to log data to the Windows Event Log in C# How to use ArrayPool and MemoryPool in C# How to use the Buffer class in C# How to use HashSet in C# How to use named and optional parameters in C# How to benchmark C# code using BenchmarkDotNet How to use fluent interfaces and method chaining in C# How to unit test static methods in C# How to refactor God objects in C# Related content feature What is Rust? Safe, fast, and easy software development Unlike most programming languages, Rust doesn't make you choose between speed, safety, and ease of use. Find out how Rust delivers better code with fewer compromises, and a few downsides to consider before learning Rust. By Serdar Yegulalp Nov 20, 2024 11 mins Rust Programming Languages Software Development how-to Kotlin for Java developers: Classes and coroutines Kotlin was designed to bring more flexibility and flow to programming in the JVM. Here's an in-depth look at how Kotlin makes working with classes and objects easier and introduces coroutines to modernize concurrency. By Matthew Tyson Nov 20, 2024 9 mins Java Kotlin Programming Languages analysis Azure AI Foundry tools for changes in AI applications Microsoft’s launch of Azure AI Foundry at Ignite 2024 signals a welcome shift from chatbots to agents and to using AI for business process automation. By Simon Bisson Nov 20, 2024 7 mins Microsoft Azure Generative AI Development Tools news Microsoft unveils imaging APIs for Windows Copilot Runtime Generative AI-backed APIs will allow developers to build image super resolution, image segmentation, object erase, and OCR capabilities into Windows applications. By Paul Krill Nov 19, 2024 2 mins Generative AI APIs Development Libraries and Frameworks Resources Videos