Операторы верхнего уровня — программы без Main методов

Не нужно явно включать Main метод в проект консольного приложения. Вместо этого можно использовать операторы верхнего уровня для минимизации объема создаваемого кода.

Инструкции верхнего уровня позволяют писать исполняемый код непосредственно в корне файла, устраняя необходимость упаковки кода в класс или метод. Это означает, что вы можете создавать программы без церемонии Program класса и Main метода. В этом случае компилятор создает Program класс с методом точки входа для приложения. Имя созданного метода не Mainявляется именем, это сведения о реализации, на которые код не может ссылаться напрямую.

Ниже приведен файл Program.cs, который является полной программой C# в C# 10:

Console.WriteLine("Hello World!");

Операторы верхнего уровня позволяют создавать простой программный код для небольших служебных программ, таких как Функции Azure и GitHub Actions. Они также помогают начинающим программистам C# начать обучение и приступить к написанию кода.

В следующих разделах описываются правила, которые определяют использование операторов верхнего уровня.

Только один файл верхнего уровня

Приложение должно иметь только одну точку входа. Проект может содержать только один файл с операторами верхнего уровня. Размещение операторов верхнего уровня в нескольких файлах в проекте приводит к следующей ошибке компилятора:

CS8802 Only one compilation unit can have top-level statements (Только одна единица компиляции может содержать операторы верхнего уровня).

В проекте может содержаться любое количество дополнительных файлов с исходным кодом, в которых нет операторов верхнего уровня.

Другие точки входа отсутствуют

Метод Main можно написать явным образом, но он не может функционировать как точка входа. Компилятор выдает следующее предупреждение:

CS7022 The entry point of the program is global code; ignoring 'Main()' entry point (Точка входа программы является глобальным кодом; точка входа Main() игнорируется).

В проекте с операторами верхнего уровня нельзя использовать параметр компилятора -main для выбора точки входа, даже если в проекте есть один или несколько методов Main.

Директивы using

Если вы включаете директивы using, они должны быть первыми в файле, как показано в следующем примере:

using System.Text;

StringBuilder builder = new();
builder.AppendLine("The following arguments are passed:");

// Display the command line arguments using the args variable.
foreach (var arg in args)
{
    builder.AppendLine($"Argument={arg}");
}

Console.WriteLine(builder.ToString());

// Return a success code.
return 0;

Глобальное пространство имен

Операторы верхнего уровня неявно находятся в глобальном пространстве имен.

Пространства имен и определения типов

Файл с операторами верхнего уровня может также содержать пространства имен и определения типов, но они должны следовать за операторами верхнего уровня. Например:

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

Операторы верхнего уровня могут ссылаться на переменную args для обращения к любым введенным аргументам командной строки. Переменная args никогда не имеет значение NULL, но ее значение Length равно нулю, если не были предоставлены аргументы командной строки. Например:

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

await

Асинхронный метод можно вызвать с помощью await. Например:

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

Код завершения для процесса

Чтобы вернуть значение int при завершении работы приложения, используйте оператор return, как в методе Main, который возвращает int. Например:

string? s = Console.ReadLine();

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

Неявный метод точки входа

Компилятор создает метод, используемый в качестве точки входа программы для проекта с операторами верхнего уровня. Сигнатура метода зависит от того, содержат ли операторы верхнего уровня ключевое слово await или оператор return. В следующей таблице показано, как будет выглядеть сигнатура метода; имя метода Main в таблице используется для удобства.

Код верхнего уровня содержит Неявная сигнатура Main
await и return. static async Task<int> Main(string[] args)
await static async Task Main(string[] args)
return static int Main(string[] args)
Ни await, ни return static void Main(string[] args)

Спецификация языка C#

Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

Спецификация компонентов — операторы верхнего уровня