Anweisungen auf oberster Ebene – Programme ohne Main Methoden

Ab C# 9 müssen Sie eine Main-Methode nicht mehr explizit in ein Konsolenanwendungsprojekt einschließen. Stattdessen können Sie die Funktion Anweisungen auf oberster Ebene verwenden, um den Code zu minimieren, den Sie schreiben müssen. In diesem Fall generiert der Compiler eine Klasse und einen Main-Methodeneinstiegspunkt für die Anwendung.

Hier ist eine Datei "Program.cs ", die ein vollständiges C#-Programm in C# 10 ist:

Console.WriteLine("Hello World!");

Mit Anweisungen auf oberster Ebene können Sie einfache Programme für kleine Dienstprogramme wie Azure Functions und GitHub Actions schreiben. Sie erleichtern auch neuen C#-Programmierern den Einstieg in das Erlernen und Schreiben von Code.

In den folgenden Abschnitten werden die Regeln für zulässige und unzulässige Anweisungen auf oberster Ebene erläutert.

Nur eine Datei auf oberster Ebene

Eine Anwendung muss nur einen Einstiegspunkt haben. Ein Projekt kann nur eine Datei mit Anweisungen auf oberster Ebene haben. Das Einfügen von Anweisungen auf oberster Ebene in mehrere Dateien in einem Projekt führt zu folgendem Compilerfehler:

CS8802 Only one compilation unit can have top-level statements (Nur eine Kompilierungseinheit kann Anweisungen auf oberster Ebene aufweisen).

Ein Projekt kann beliebig viele zusätzliche Quellcodedateien aufweisen, die keine Anweisungen auf oberster Ebene aufweisen.

Keine weiteren Einstiegspunkte

Sie können eine Main-Methode explizit schreiben, aber sie kann nicht als Einstiegspunkt fungieren. Der Compiler gibt folgende Warnung aus:

CS7022 The entry point of the program is global code; ignoring 'Main()' entry point (Der Einstiegspunkt des Programms ist globaler Code. Der Einstiegspunkt 'Main()' wird ignoriert).

In einem Projekt mit Anweisungen auf oberster Ebene können Sie die Compileroption -main nicht verwenden, um den Einstiegspunkt auszuwählen, auch wenn das Projekt mindestens eine Main-Methode aufweist.

using-Direktiven

Wenn Sie using-Direktiven einschließen, müssen diese zuerst in der Datei vorkommen, wie im folgenden Beispiel gezeigt:


using System.Text;

StringBuilder builder = new();
builder.AppendLine("Hello");
builder.AppendLine("World!");

Console.WriteLine(builder.ToString());

Globaler Namespace

Anweisungen auf oberster Ebene sind implizit im globalen Namespace enthalten.

Namespaces und Typdefinitionen

Eine Datei mit Anweisungen auf oberster Ebene kann auch Namespaces und Typdefinitionen enthalten, sie müssen aber nach den Anweisungen auf oberster Ebene platziert werden. Beispiel:

MyClass.TestMethod();
MyNamespace.MyClass.MyMethod();

public class MyClass
{
    public static void TestMethod()
    {
        Console.WriteLine("Hello World!");
    }

}

namespace MyNamespace
{
    class MyClass
    {
        public static void MyMethod()
        {
            Console.WriteLine("Hello World from MyNamespace.MyClass.MyMethod!");
        }
    }
}

args

Anweisungen auf oberster Ebene können auf die args-Variable verweisen, um auf eingegebene Befehlszeilenargumente zuzugreifen. Die args-Variable ist nie NULL, aber Ihr Length ist null, wenn keine Befehlszeilenargumente angegeben wurden. Beispiel:

if (args.Length > 0)
{
    foreach (var arg in args)
    {
        Console.WriteLine($"Argument={arg}");
    }
}
else
{
    Console.WriteLine("No arguments");
}

await

Sie können eine asynchrone Methode aufrufen, indem Sie await verwenden. Beispiel:

Console.Write("Hello ");
await Task.Delay(5000);
Console.WriteLine("World!");

Exitcode für den Prozess

Um beim Beenden der Anwendung einen int-Wert zurückzugeben, verwenden Sie die return-Anweisung wie in einer Main-Methode, die einen int-Wert zurückgibt. Beispiel:

string? s = Console.ReadLine();

int returnValue = int.Parse(s ?? "-1");
return returnValue;

Implizite Einstiegspunktmethode

Der Compiler generiert eine Methode, die als Programmeinstiegspunkt für ein Projekt mit Anweisungen auf oberster Ebene fungiert. Der Name dieser Methode ist eigentlich nicht Main, sondern ein Implementierungsdetail, auf das Ihr Code nicht direkt verweisen kann. Die Signatur der Methode hängt davon ab, ob die Anweisungen auf oberster Ebene das await-Schlüsselwort oder die return-Anweisung enthalten. Die folgende Tabelle zeigt, wie die Methodensignatur aussehen würde, wobei der Einfachheit halber der Methodenname Main in der Tabelle verwendet wird.

Code auf oberster Ebene enthält Folgendes: Implizite Main-Signatur
await und return static async Task<int> Main(string[] args)
await static async Task Main(string[] args)
return static int Main(string[] args)
Kein await oder return static void Main(string[] args)

C#-Sprachspezifikation

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Featurespezifikation – Anweisungen auf oberster Ebene