Skip to content

C# Top-Level Statements — Complete Guide

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about C# Top. We cover key concepts, practical examples, and best practices.

You create a new console app and C# generates a Program class with a Main method, namespaces, and using directives before you can write Hello, World!. Top-level statements remove this boilerplate so only your code remains.

Wrong

using System;

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

Output: "Hello, World!" — but eight lines of boilerplate for one line of actual code.

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

Output: "Hello, World!".

Top-level statements let you write any executable statement directly in the file. The compiler generates the Main method and surrounding class automatically.

You can still access command-line args, return values, and use await:

using System.Net.Http;

Console.WriteLine($"Args: {args.Length}");
var client = new HttpClient();
var response = await client.GetStringAsync("https://example.com");
Console.WriteLine(response.Length);
return 0;

Prevention

  • Use top-level statements for simple programs, scripts, and quick prototypes.
  • Move to a traditional Main method when the program grows beyond ~50 lines.
  • Keep implicit using directives enabled — System, System.Collections.Generic, System.Linq, etc., are auto-imported.
  • Use args as the built-in variable for command-line arguments.
  • Use await directly at the top level — the compiler generates the async Main for you.
  • Add global using for commonly used namespaces across multiple files.

Common Mistakes with top level statement

  1. Mixing let bindings with <- bindings in do notation, producing type errors
  2. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
  3. Non-exhaustive pattern matches that compile with warnings then crash at runtime

These mistakes appear frequently in real-world CSHARP code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

Can I have multiple files with top-level statements?

No. Only one file in the project can use top-level statements. All other files must use the traditional class-and-Main approach. The compiler picks the single entry point file automatically.

How do I add async support?

Just use await directly. The compiler detects the await keyword and generates an async Task<int> Main method. No explicit async Main declaration is needed.

Can I define methods in top-level statements?

Yes. You can declare local functions after the top-level statements. The compiler treats them as methods within the generated Program class: Console.WriteLine(Foo()); static int Foo() => 42;.

Top-level statements are used in DodaTech's build scripts and automation tools. For more C#, visit DodaTech.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro