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

Начиная с версии C# 9, метод Main не нужно явно включать в проект консольного приложения. Вместо этого можно использовать операторы верхнего уровня для минимизации объема создаваемого кода. В этом случае компилятор создает класс и точку входа метода 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("Hello");
builder.AppendLine("World!");

Console.WriteLine(builder.ToString());

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

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

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

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

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;

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

Компилятор создает метод, используемый в качестве точки входа программы для проекта с операторами верхнего уровня. Имя этого метода на самом деле не Main, это описание реализации, на которое код не может ссылаться напрямую. Сигнатура метода зависит от того, содержат ли операторы верхнего уровня ключевое слово 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#.

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