[C#] Try Top-level statements

Intro

From .NET 6, Program.cs is made with "Top-level statements".
In this time, I will try using "Top-level statements".

Environments

  • .NET ver.6.0.101

Trying "Top-level statements" with default console project

First, I create a console project by "dotnet new console".

Program.cs

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

I decompile it by ilspy-vscode.

Program.cs

using System;
using System.Runtime.CompilerServices;

[CompilerGenerated]
internal class Program
{
    private static void <Main>$(string[] args)
    {
        Console.WriteLine("Hello, World!");
    }
}

From the result, a class and a main method were generated.

I can get command-line arguments from "args".

Program.cs

foreach(var a in args)
{
    Console.WriteLine($"arcuments: {a}");    
}
Console.WriteLine("Hello, World!");

namespace ?

Can I put the class in namespaces? No.

Program.cs

namespace TopLevelStatementSample;

// Compiling error
Console.WriteLine("Hello, World!");

Program.cs

namespace TopLevelStatementSample
{
    // Compiling error
    Console.WriteLine("Hello, World!");
}
error CS0116: A namespace cannot directly contain members such as fields, methods or statements

Of course I also can't put it into namespaces with curly braces.

Multiple files

Can I add one more files what is written by "Top-level statements"? No.

SampleClass.cs

// Compiling error
void Greet(string message)
{
    Console.WriteLine("Hello sample class");
}
error CS8802: Only one compilation unit can have top-level statements.

Adding another main class

Can I add one more files what has static "Main" method? Yes.

SampleClass.cs

namespace TopLevelStatementSample;
public class SampleClass
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Hello sample class");
    }
}

But I get a warning and "SampleClass" isn't treated as the main class.

warning CS7022: The entry point of the program is global code; ignoring 'SampleClass.Main(string[])' entry point.

Result

Hello, World!

Add classes, methods, and variables

I can add classes into Program.cs.
But I only can write it at the bottom of the file.

classes

Program.cs

using TopLevelStatementSample;
class Sample1
{
    // can't write classes at the top of the file.
}
// Compiling error
Console.WriteLine("Hello, World!");

class Sample2
{
    // can't write classes at the middle of the file.    
}
// Compiling error
SampleClass.Main(new string[0]);

var s3 = new Sample3();
class Sample3
{
    // OK.    
}

methods and variables

I can write methods and variables at everywhere in the file.

Program.cs

using TopLevelStatementSample;
void Greet(string message)
{
    Console.WriteLine(message);
}
// OK
var message = "Hello message";
// OK
Greet(message);

SampleClass.Main(new string[0]);

Because they are treated as global, other classes also can look them.
But they can't call any methods and variables in Program.cs.

SampleClass.cs

namespace TopLevelStatementSample;
public class SampleClass
{
    public static void Main(string[] args)
    {
        // Compiling error
        Greet("Hello sample class");
    }
}
error CS8801: Cannot use local variable or local function 'Greet' declared in a top-level statement in this context.

Outro

Because "Top-level statements" are only for the entry point, they will only be created by "dotnet new" command.

I'm worried about implicit processing(ex. command-line arguments), but I think that the problem will disappear as you get used to it.

Resources

25