[C#] Try Top-level statements

masanori_msl

Masui Masanori

Posted on December 18, 2021

[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!");
Enter fullscreen mode Exit fullscreen mode

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!");
    }
}
Enter fullscreen mode Exit fullscreen mode

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!");
Enter fullscreen mode Exit fullscreen mode

namespace ?

Can I put the class in namespaces? No.

Program.cs

namespace TopLevelStatementSample;

// Compiling error
Console.WriteLine("Hello, World!");
Enter fullscreen mode Exit fullscreen mode

Program.cs

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

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");
}
Enter fullscreen mode Exit fullscreen mode
error CS8802: Only one compilation unit can have top-level statements.
Enter fullscreen mode Exit fullscreen mode

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");
    }
}
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

Result

Hello, World!
Enter fullscreen mode Exit fullscreen mode

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.    
}
Enter fullscreen mode Exit fullscreen mode

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]);
Enter fullscreen mode Exit fullscreen mode

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");
    }
}
Enter fullscreen mode Exit fullscreen mode
error CS8801: Cannot use local variable or local function 'Greet' declared in a top-level statement in this context.
Enter fullscreen mode Exit fullscreen mode

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

💖 💪 🙅 🚩
masanori_msl
Masui Masanori

Posted on December 18, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related