A Guide to C# 9 Top-Level Statements

An introduction to C# 9's top-level statements feature, which allows you to write simple programs without the ceremony of a Program class and a Main method. Learn how it simplifies code and makes C# more beginner-friendly.

For years, the simplest "Hello, World!" program in C# has been surprisingly verbose. You needed a Program class and a static void Main method, all just to print a single line to the console. This ceremony could be intimidating for beginners and was unnecessary for small scripts and utilities.

C# 9, released with .NET 5, introduces a feature to solve this: top-level statements.

The Old Way: The Program.cs Boilerplate

Before C# 9, the minimal C# program looked like this:

using System;

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

All of this code was just boilerplate to get to the one line that actually does something.

The New Way: Top-Level Statements

With C# 9, you can now write that same program in a single line in your Program.cs file:

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

That's it. You can just write your statements at the top level of a file, and the C# compiler will generate the Program class and Main method for you behind the scenes.

How Does It Work?

The compiler takes your top-level statements and synthesizes them into the Main method of a generated Program class. This means you can only have one file with top-level statements in your entire project, as a project can only have one entry point.

You can still do everything you could do in a traditional Main method:

Accessing Command-Line Arguments:

The args array is magically available to you.

if (args.Length > 0)
{
    Console.WriteLine($"Hello, {args[0]}!");
}
else
{
    Console.WriteLine("Hello, World!");
}

Returning an Exit Code:

You can return an integer value, which will be used as the process exit code.

return 1; // Indicates an error

Using async/await:

You can also use await, and the compiler will generate an async Task Main method for you.

using System.Net.Http;

var client = new HttpClient();
var response = await client.GetStringAsync("https://www.example.com");
Console.WriteLine(response.Length);

Where Should You Use Top-Level Statements?

This feature is ideal for:

  • Beginners: It makes C# much more approachable for people learning to code, as they don't have to understand classes, methods, and namespaces just to write their first program.
  • Small Utilities and Scripts: It's perfect for writing small console applications and scripts where the boilerplate of a full Program class is unnecessary.
  • Minimal Web APIs: In .NET 6, this feature would become the foundation for the new minimal API syntax, allowing you to create a web API in just a few lines of code.

For larger, more complex console applications, you may still prefer the structure of a traditional Program class with an explicit Main method, but for many use cases, top-level statements provide a much cleaner and more concise starting point.

Conclusion

Top-level statements are a fantastic quality-of-life improvement for the C# language. By removing unnecessary boilerplate, they make the language easier to learn and faster to write for simple applications. It's a perfect example of how C# continues to evolve to meet the needs of modern developers, from large-scale enterprise applications to small, simple scripts.

Comments

Share your thoughts and insights in the comments below. We'd love to hear your perspective on this topic!

Geek Cafe LogoGeek Cafe

Your trusted partner for cloud architecture, development, and technical solutions. Let's build something amazing together.

Quick Links

© 2025 Geek Cafe LLC. All rights reserved.

Research Triangle Park, North Carolina

Version: 8.9.22