Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Tip
New to developing software? Start with the Get started tutorials first. Those tutorials use top-level statements, which is simpler for new apps.
Working with an existing codebase? Many existing applications use an explicit Main method. This article explains how it works and how to use it effectively.
When you start a C# application, the runtime calls the Main method. The Main method is the entry point of a C# application.
A C# program can have only one entry point. If you have more than one class with a Main method, you must use the StartupObject compiler option when you compile your program to specify which Main method serves as the entry point. For more information, see StartupObject (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);
}
}
Overview
The Main method is the entry point of an executable program. When your program starts, the runtime calls Main before any other code runs. When Main returns, the program ends. You declare Main with these rules:
- You must declare
Maininside a class or struct. The enclosingclasscan bestatic. Mainmust bestatic.Maincan have any access modifier.Maincan returnvoid,int,Task, orTask<int>.- If and only if
Mainreturns aTaskorTask<int>, the declaration ofMaincan include theasyncmodifier. This rule specifically excludes anasync void Mainmethod. - You can declare the
Mainmethod with or without astring[]parameter that contains command-line arguments. When you use Visual Studio to create Windows applications, you can add the parameter manually or else use the GetCommandLineArgs() method to obtain the command-line arguments. Parameters are zero-indexed command-line arguments. Unlike C and C++, the name of the program isn't treated as the first command-line argument in theargsarray, but it's the first element of the GetCommandLineArgs() method.
The following list shows permutations of Main 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 implicitly private by default. You can specify any explicit access modifier.
The following table summarizes all valid Main signatures and when to use each one:
Main declaration |
Uses args |
contains await |
Returns exit code |
|---|---|---|---|
static void Main() |
No | No | No |
static int Main() |
No | No | Yes |
static void Main(string[] args) |
Yes | No | No |
static int Main(string[] args) |
Yes | No | Yes |
static async Task Main() |
No | Yes | No |
static async Task<int> Main() |
No | Yes | Yes |
static async Task Main(string[] args) |
Yes | Yes | No |
static async Task<int> Main(string[] args) |
Yes | Yes | Yes |
Choose the simplest signature that fits your needs. If you don't need command-line arguments, omit the string[] args parameter. If you don't need to return an exit code, use void or Task. If you need to call asynchronous methods, use async with a Task or Task<int> return type.
Main() return values
When you return int or Task<int>, your program can send status information to other programs or scripts that run the executable. A return value of 0 usually means success, and a nonzero value means there's an error.
The following example returns an exit code:
class MainReturnValTest
{
static int Main()
{
//...
return 0;
}
}
After running the program, you can check the exit code. In PowerShell, use $LastExitCode. In a batch file or shell script, use %ERRORLEVEL%.
If your Main method uses await, declare it as async with a Task or Task<int> return type. The runtime calls Main and waits for the returned Task to complete before the process exits. The return type can't be void or int because the async modifier requires a return type that the runtime can await—void and int don't represent ongoing work, so the process could exit before asynchronous operations finish. Use Task when you don't need an exit code, or Task<int> when you do:
class Program
{
static async Task<int> Main(string[] args)
{
return await AsyncConsoleWork();
}
private static async Task<int> AsyncConsoleWork()
{
return 0;
}
}
Command-line arguments
Include a string[] args parameter in your Main declaration to accept command-line arguments. If you don't need them, omit the parameter. The args parameter is a String array that's never null—if no arguments are provided, its Length is zero.
You can convert string arguments to other types by using Parse or Convert:
long num = long.Parse(args[0]);
Tip
Parsing command-line arguments can be complex. Consider using the System.CommandLine library to simplify the process.
For a working example, see How to display command-line arguments.
C# language specification
For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.