[C#] Try Top-level statements
Tags: dotnet, csharp
Published: 2021-12-18 00:57:41

## 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
```cs
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
```

I decompile it by ilspy-vscode.

* [GitHub - icsharpcode/ilspy-vscode](https://github.com/icsharpcode/ilspy-vscode)

#### Program.cs
```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
```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
```cs
namespace TopLevelStatementSample;

// Compiling error
Console.WriteLine("Hello, World!");
```
#### Program.cs
```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
```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
```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
```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
```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
```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
* [Top-level statements - C# 9.0 feature specifications | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/top-level-statements)
* [エントリー ポイント - 	C# によるプログラミング入門 | ++C++; // 未確認飛行 C](https://ufcpp.net/study/csharp/misc/miscentrypoint/#top-level-statements)