Notiz
Zougrëff op dës Säit erfuerdert Autorisatioun. Dir kënnt probéieren, Iech unzemellen oder Verzeechnesser ze änneren.
Zougrëff op dës Säit erfuerdert Autorisatioun. Dir kënnt probéieren, Verzeechnesser ze änneren.
The runtime calls the Main method when you start a C# application. 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);
}
}
You can also use top-level statements in one file as the entry point for your application. Like the Main method, top-level statements can return values and access command-line arguments. For more information, see Top-level statements. The following example uses a foreach loop to display the command-line arguments by using the args 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 be file-based apps, where a single file contains the program. You run file-based apps by using the command dotnet <file.cs>, or by using the #!/usr/bin/env dotnet run directive as the first line (Unix shells only).
Overview
- The
Mainmethod is the entry point of an executable program. It's where the program control starts and ends. - 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 using 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 the most common 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.
Tip
By using async and Task or Task<int> return types, you simplify program code when console applications need to start and await asynchronous operations in Main.
Main() return values
You can return an int from the Main method by defining the method in one of the following ways:
Main declaration |
Main method code |
|---|---|
static int Main() |
No use of args or await |
static int Main(string[] args) |
Uses args but not await |
static async Task<int> Main() |
Uses await but not args |
static async Task<int> Main(string[] args) |
Uses args and await |
If the return value from Main isn't used, returning void or Task allows for slightly simpler code.
Main declaration |
Main method code |
|---|---|
static void Main() |
No use of args or await |
static void Main(string[] args) |
Uses args but not await |
static async Task Main() |
Uses await but not args |
static async Task Main(string[] args) |
Uses args and await |
However, returning int or Task<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 this get-started article.
Create a new application by running dotnet new console. Modify the Main method in Program.cs as follows:
class MainReturnValTest
{
static int Main()
{
//...
return 0;
}
}
Remember to save this program as MainReturnValTest.cs.
When you execute a program in Windows, the system stores any value returned from the Main function in an environment variable. You can retrieve this environment variable by using ERRORLEVEL from a batch file, or $LastExitCode from PowerShell.
You can build the application by using the dotnet CLI dotnet 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 as test.ps1 in the folder that contains the project. Run the PowerShell script by typing test.ps1 at the PowerShell prompt.
Because the code returns zero, the batch file reports success. However, if you change MainReturnValTest.cs to return a nonzero value and then recompile the program, subsequent execution of the PowerShell script reports failure.
dotnet run
if ($LastExitCode -eq 0) {
Write-Host "Execution succeeded"
} else
{
Write-Host "Execution Failed"
}
Write-Host "Return value = " $LastExitCode
Execution succeeded
Return value = 0
Async Main return values
When you declare an async return value for Main, the compiler generates the boilerplate code for calling asynchronous methods in Main:
class Program
{
static async Task<int> Main(string[] args)
{
return await AsyncConsoleWork();
}
private static async Task<int> AsyncConsoleWork()
{
return 0;
}
}
In both examples, the main body of the program is within the body of the AsyncConsoleWork() method.
An advantage of declaring Main as async is that the compiler always generates the correct code.
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. 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 use the async modifier on the Main method, the compiler generates the same code.
Command-line arguments
You can send arguments to the Main method by defining the method in one of the following ways:
Main declaration |
Main method code |
|---|---|
static void Main(string[] args) |
No return value or await |
static int Main(string[] args) |
Returns a value but doesn't use await |
static async Task Main(string[] args) |
Uses await but doesn't return a value |
static async Task<int> Main(string[] args) |
Return a value and uses await |
If you don't use the arguments, you can omit args from the method declaration for slightly simpler code:
Main declaration |
Main method code |
|---|---|
static void Main() |
No return value or await |
static int Main() |
Returns a value but doesn't use await |
static async Task Main() |
Uses await but doesn't return a value |
static async Task<int> Main() |
Returns a value and uses await |
Note
You can also use Environment.CommandLine or Environment.GetCommandLineArgs to access the command-line arguments from any point in a console or Windows Forms application. To enable command-line arguments in the Main method declaration in a Windows Forms application, you must manually modify the declaration of Main. The code generated by the Windows Forms designer creates Main without an input parameter.
The parameter of the Main method is a String array that represents the command-line arguments. Usually, you determine whether arguments exist by testing the Length property, for example:
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
return 1;
}
Tip
The args array can't be null. So, it's safe to access the Length property without null checking.
You can also convert the string arguments to numeric types by using the Convert class or the Parse method. For example, the following statement converts the string to a long number by using the Parse method:
long num = Int64.Parse(args[0]);
It's also possible to use the C# type long, which aliases Int64:
long num = long.Parse(args[0]);
You can also use the Convert class method ToInt64 to do the same thing:
long num = Convert.ToInt64(s);
For more information, see Parse and Convert.
Tip
Parsing command-line arguments can be complex. Consider using the System.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:
- Paste the following code into any text editor, and then save the file as a text file with the name Factorial.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 the Main method, the program tests if input arguments weren't supplied by comparing the length of the args argument to 0 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 in result variable of type long), the verbose result is printed depending on the result variable.
From the Start screen or Start menu, open a Visual Studio Developer Command Prompt window, and then navigate to the folder that contains the file that you created.
To compile the application, enter the following command:
dotnet buildIf your application has no compilation errors, the build process creates a binary file named Factorial.dll.
Enter the following command to calculate the factorial of 3:
dotnet run -- 3If you enter 3 on the command line as the program's argument, the output reads:
The factorial of 3 is 6.
Note
When running an application in Visual Studio, specify command-line arguments in the Debug Page, Project Designer.
C# language specification
For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.