Значения, возвращаемые методом Main() (Руководство по программированию на C#)Main() return values (C# Programming Guide)

Метод Main может возвращать значение void:The Main method can return void:

static void Main()
{
    //...
}

Он также может возвращать значение типа int:It can also return an int:

static int Main()
{
    //...
    return 0;
}

Если значение, возвращаемое методом Main, не используется, то указание в качестве возвращаемого типа void несколько упрощает код.If the return value from Main is not used, returning void allows for slightly simpler code. Однако возврат целого значения позволяет программе передавать информацию о своем состоянии другим программам и скриптам, которые вызывают исполняемый файл.However, returning an integer enables the program to communicate status information to other programs or scripts that invoke the executable file. Возвращаемое значение Main рассматривается как код выхода процесса.The return value from Main is treated as the exit code for the process. Если void возвращается из Main, код завершения будет неявно задан как 0.If void is returned from Main, the exit code will be implicitly 0. В приведенном ниже примере показано, как получить доступ к значению, возвращаемому методом Main.The following example shows how the return value from Main can be accessed.

ПримерExample

В этом примере используются программы командной строки .NET Core.This example uses .NET Core command-line tools. Если вы не знакомы с программами командной строки .NET Core, можете обратиться к этой статье по началу работы.If you are unfamiliar with .NET Core command-line tools, you can learn about them in this get-started article.

Измените метод Main в файле program.cs следующим образом:Modify the Main method in program.cs as follows:

// Save this program as MainReturnValTest.cs.
class MainReturnValTest
{
    static int Main()
    {
        //...
        return 0;
    }
}

При запуске программы в Windows значение, возвращаемое функцией Main, сохраняется в переменной среды.When a program is executed in Windows, any value returned from the Main function is stored in an environment variable. Эту переменную среды можно получить из пакетного файла с помощью ERRORLEVEL или в PowerShell с помощью $LastExitCode.This environment variable can be retrieved using ERRORLEVEL from a batch file, or $LastExitCode from PowerShell.

Для сборки приложения можно выполнить команду dotnet build интерфейса командной строки .NET.You can build the application using the dotnet CLI dotnet build command.

Затем создайте скрипт PowerShell для запуска приложения и отображения результата.Next, create a PowerShell script to run the application and display the result. Вставьте следующий код в текстовый файл и сохраните его под именем test.ps1 в папке проекта.Paste the following code into a text file and save it as test.ps1 in the folder that contains the project. Запустите скрипт PowerShell, введя команду test.ps1 в командной строке PowerShell.Run the PowerShell script by typing test.ps1 at the PowerShell prompt.

Так как код возвращает нулевое значение, пакетный файл сообщает об успехе.Because the code returns zero, the batch file will report success. Но если изменить файл MainReturnValTest.cs, чтобы он возвращал ненулевое значение, и затем повторно скомпилировать программу, то при последующем выполнении скрипта PowerShell будет выдано сообщение об ошибке.However, if you change MainReturnValTest.cs to return a non-zero value and then recompile the program, subsequent execution of the PowerShell script will report failure.

dotnet run
if ($LastExitCode -eq 0) {
    Write-Host "Execution succeeded"
} else
{
    Write-Host "Execution Failed"
}
Write-Host "Return value = " $LastExitCode

Пример полученных результатовSample output

Execution succeeded
Return value = 0

Значения, возвращаемые асинхронным методом mainAsync Main return values

Возвращаемые значения асинхронного метода main перемещают стандартный код, необходимый для вызова асинхронных методов в Main, в код, созданный компилятором.Async Main return values move the boilerplate code necessary for calling asynchronous methods in Main to code generated by the compiler. Ранее для вызова асинхронного кода и для запуска программы до завершения асинхронной операции приходилось использовать следующую конструкцию:Previously, you would need to write this construct to call asynchronous code and ensure your program ran until the asynchronous operation completed:

public static void Main()
{
    AsyncConsoleWork().GetAwaiter().GetResult();
}

private static async Task<int> AsyncConsoleWork()
{
    // Main body here
    return 0;
}

Теперь ее можно заменить на:Now, this can be replaced by:

static async Task<int> Main(string[] args)
{
    return await AsyncConsoleWork();
}

Преимущество нового синтаксиса состоит в том, что компилятор всегда формирует правильный код.The advantage of the new syntax is that the compiler always generates the correct code.

Код, создаваемый компиляторомCompiler-generated code

Если точка входа приложения возвращает Task или Task<int>, то компилятор создает новую точку входа, которая вызывает метод точки входа, объявленный в коде приложения.When the application entry point returns a Task or Task<int>, the compiler generates a new entry point that calls the entry point method declared in the application code. Предположим, что эта точка входа называется $GeneratedMain. В этом случае компилятор создает следующий код для этих точек входа:Assuming that this entry point is called $GeneratedMain, the compiler generates the following code for these entry points:

  • static Task Main() приводит к тому, что компилятор формирует эквивалент private static void $GeneratedMain() => Main().GetAwaiter().GetResult();static Task Main() results in the compiler emitting the equivalent of private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task Main(string[]) приводит к тому, что компилятор формирует эквивалент private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();static Task Main(string[]) results in the compiler emitting the equivalent of private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
  • static Task<int> Main() приводит к тому, что компилятор формирует эквивалент private static int $GeneratedMain() => Main().GetAwaiter().GetResult();static Task<int> Main() results in the compiler emitting the equivalent of private static int $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task<int> Main(string[]) приводит к тому, что компилятор формирует эквивалент private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();static Task<int> Main(string[]) results in the compiler emitting the equivalent of private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();

Примечание

Если бы в примерах использовался модификатор async метода Main, компилятор сформировал бы точно такой же код.If the examples used async modifier on the Main method, the compiler would generate the same code.

См. такжеSee also