Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft EdgeMore info about Internet Explorer and Microsoft Edge
Table of contentsExit focus mode

Main() and command-line arguments

  • 2025-07-01
Feedback

In this article

TheMain method is the entry point of a C# application. When the application is started, theMain method is the first method that is invoked.

There can only be one entry point in a C# program. If you have more than one class that has aMain method, you must compile your program with theStartupObject compiler option to specify whichMain method to use as the entry point. For more information, seeStartupObject (C# Compiler Options). The following example displays the number of command line arguments as its first action:

class TestClass{    static void Main(string[] args)    {        Console.WriteLine(args.Length);    }}

You can also use top-level statements in one file as the entry point for your application. Just as theMain method, top-level statements can alsoreturn values and accesscommand-line arguments. For more information, seeTop-level statements. The following example uses aforeach loop to display the command-line arguments using theargs variable, and at the end of the program returns a success code (0):

using System.Text;StringBuilder builder = new();builder.AppendLine("The following arguments are passed:");foreach (var arg in args){    builder.AppendLine($"Argument={arg}");}Console.WriteLine(builder.ToString());return 0;

Beginning with C# 14, programs can befile based programs, where a single file contains the program. You runfile based programs with the commanddotnet run <file.cs>, or using the#!/usr/local/share/dotnet/dotnet run directive as the first line (unix shells only).

Overview

  • TheMain method is the entry point of an executable program; it's where the program control starts and ends.
  • Main must be declared inside a class or struct. The enclosingclass can bestatic.
  • Main must bestatic.
  • Main can have anyaccess modifier (exceptfile).
  • Main can either have avoid,int,Task, orTask<int> return type.
  • If and only ifMain returns aTask orTask<int>, the declaration ofMain can include theasync modifier. This rule specifically excludes anasync void Main method.
  • TheMain method can be declared with or without astring[] parameter that contains command-line arguments. When using Visual Studio to create Windows applications, you can add the parameter manually or else use theGetCommandLineArgs() method to obtain the command-line arguments. Parameters are read as zero-indexed command-line arguments. Unlike C and C++, the name of the program isn't treated as the first command-line argument in theargs array, but it's the first element of theGetCommandLineArgs() method.

The following list shows the most commonMain declarations:

static void Main() { }static int Main() { }static void Main(string[] args) { }static int Main(string[] args) { }static async Task Main() { }static async Task<int> Main() { }static async Task Main(string[] args) { }static async Task<int> Main(string[] args) { }

The preceding examples don't specify an access modifier, so they're implicitlyprivate by default. It's possible to specify any explicit access modifier.

Tip

The addition ofasync andTask,Task<int> return types simplifies program code when console applications need to start andawait asynchronous operations inMain.

Main() return values

You can return anint from theMain method by defining the method in one of the following ways:

Main declarationMain method code
static int Main()No use ofargs orawait
static int Main(string[] args)Usesargs but notawait
static async Task<int> Main()Usesawait but notargs
static async Task<int> Main(string[] args)Usesargs andawait

If the return value fromMain isn't used, returningvoid orTask allows for slightly simpler code.

Main declarationMain method code
static void Main()No use ofargs orawait
static void Main(string[] args)Usesargs but notawait
static async Task Main()Usesawait but notargs
static async Task Main(string[] args)Usesargs andawait

However, returningint orTask<int> enables the program to communicate status information to other programs or scripts that invoke the executable file.

The following example shows how the exit code for the process can be accessed.

This example uses.NET Core command-line tools. If you're unfamiliar with .NET Core command-line tools, you can learn about them in thisget-started article.

Create a new application by runningdotnet new console. Modify theMain method inProgram.cs as follows:

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

Remember to save this program asMainReturnValTest.cs.

When a program is executed in Windows, any value returned from theMain function is stored in an environment variable. This environment variable can be retrieved usingERRORLEVEL from a batch file, or$LastExitCode from PowerShell.

You can build the application using thedotnet CLIdotnet build command.

Next, create a PowerShell script to run the application and display the result. Paste the following code into a text file and save it astest.ps1 in the folder that contains the project. Run the PowerShell script by typingtest.ps1 at the PowerShell prompt.

Because the code returns zero, the batch file reports success. However, if you change MainReturnValTest.cs to return a non-zero value and then recompile the program, subsequent execution of the PowerShell script reports failure.

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

Async Main return values

When you declare anasync return value forMain, the compiler generates the boilerplate code for calling asynchronous methods inMain:

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

In both examples main body of the program is within the body ofAsyncConsoleWork() method.

An advantage of declaringMain asasync is that the compiler always generates the correct code.

When the application entry point returns aTask orTask<int>, the compiler generates a new entry point that calls the entry point method declared in the application code. Assuming that this entry point is called$GeneratedMain, the compiler generates the following code for these entry points:

  • static Task Main() results in the compiler emitting the equivalent ofprivate static void $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task Main(string[]) results in the compiler emitting the equivalent ofprivate static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
  • static Task<int> Main() results in the compiler emitting the equivalent ofprivate static int $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task<int> Main(string[]) results in the compiler emitting the equivalent ofprivate static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();

Note

If the examples usedasync modifier on theMain method, the compiler would generate the same code.

Command-Line Arguments

You can send arguments to theMain method by defining the method in one of the following ways:

Main declarationMain method code
static void Main(string[] args)No return value orawait
static int Main(string[] args)Returns a value but doesn't useawait
static async Task Main(string[] args)Usesawait but doesn't return a value
static async Task<int> Main(string[] args)Return a value and usesawait

If the arguments aren't used, you can omitargs from the method declaration for slightly simpler code:

Main declarationMain method code
static void Main()No return value orawait
static int Main()Returns a value but doesn't useawait
static async Task Main()Usesawait but doesn't return a value
static async Task<int> Main()Returns a value and usesawait

Note

You can also useEnvironment.CommandLine orEnvironment.GetCommandLineArgs to access the command-line arguments from any point in a console or Windows Forms application. To enable command-line arguments in theMain method declaration in a Windows Forms application, you must manually modify the declaration ofMain. The code generated by the Windows Forms designer createsMain without an input parameter.

The parameter of theMain method is aString array that represents the command-line arguments. Usually you determine whether arguments exist by testing theLength property, for example:

if (args.Length == 0){    System.Console.WriteLine("Please enter a numeric argument.");    return 1;}

Tip

Theargs array can't be null. So, it's safe to access theLength property without null checking.

You can also convert the string arguments to numeric types by using theConvert class or theParse method. For example, the following statement converts thestring to along number by using theParse method:

long num = Int64.Parse(args[0]);

It's also possible to use the C# typelong, which aliasesInt64:

long num = long.Parse(args[0]);

You can also use theConvert class methodToInt64 to do the same thing:

long num = Convert.ToInt64(s);

For more information, seeParse andConvert.

Tip

Parsing command-line arguments can be complex. Consider using theSystem.CommandLine library (currently in beta) to simplify the process.

The following example shows how to use command-line arguments in a console application. The application takes one argument at run time, converts the argument to an integer, and calculates the factorial of the number. If no arguments are supplied, the application issues a message that explains the correct usage of the program.

To compile and run the application from a command prompt, follow these steps:

  1. Paste the following code into any text editor, and then save the file as a text file with the nameFactorial.cs.

    public class Functions{    public static long Factorial(int n)    {        // Test for invalid input.        if ((n < 0) || (n > 20))        {            return -1;        }        // Calculate the factorial iteratively rather than recursively.        long tempResult = 1;        for (int i = 1; i <= n; i++)        {            tempResult *= i;        }        return tempResult;    }}class MainClass{    static int Main(string[] args)    {        if (args.Length == 0)        {            Console.WriteLine("Please enter a numeric argument.");            Console.WriteLine("Usage: Factorial <num>");            return 1;        }        int num;        bool test = int.TryParse(args[0], out num);        if (!test)        {            Console.WriteLine("Please enter a numeric argument.");            Console.WriteLine("Usage: Factorial <num>");            return 1;        }        long result = Functions.Factorial(num);        if (result == -1)            Console.WriteLine("Input must be >= 0 and <= 20.");        else            Console.WriteLine($"The Factorial of {num} is {result}.");        return 0;    }}

    At the beginning of theMain method the program tests if input arguments weren't supplied comparing length ofargs argument to0 and displays the help if no arguments are found.
    If arguments are provided (args.Length is greater than 0), the program tries to convert the input arguments to numbers. This example throws an exception if the argument isn't a number.
    After factorial is calculated (stored inresult variable of typelong), the verbose result is printed depending on theresult variable.

  2. From theStart screen orStart menu, open a Visual StudioDeveloper Command Prompt window, and then navigate to the folder that contains the file that you created.

  3. To compile the application, enter the following command:

    dotnet build

    If your application has no compilation errors, a binary file namedFactorial.dll is created.

  4. Enter the following command to calculate the factorial of 3:

    dotnet run -- 3

  5. If 3 is entered on command line as the program's argument, the output reads:The factorial of 3 is 6.

Note

When running an application in Visual Studio, you can specify command-line arguments in theDebug Page, Project Designer.

C# language specification

For more information, see theC# Language Specification. The language specification is the definitive source for C# syntax and usage.

See also

Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, seeour contributor guide.

Feedback

Was this page helpful?

YesNo

In this article

Was this page helpful?

YesNo