You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Clarify that the file modifier isn't an access modifier, it's a different type of modifier. (#50589)
* Fix technical errors on the `file` modifier
The `file` modifier isn't classified as an access modifier. It's a modifier that can't be combined with any other access modifier, and can only be applied to top-level types.
* Do a full edit pass
* Fix lint issues
* Apply suggestions from code review
Co-authored-by: Copilot <[email protected]>
* Fix snippets, update code
* fix snippet build, update some links
* lint
* Update docs/csharp/fundamentals/program-structure/main-command-line.md
Co-authored-by: Genevieve Warren <[email protected]>
---------
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Genevieve Warren <[email protected]>
Copy file name to clipboardExpand all lines: docs/csharp/fundamentals/program-structure/main-command-line.md
+41-41Lines changed: 41 additions & 41 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
title: "Main() and command-line arguments"
3
3
description: Learn about Main() and command-line arguments. The 'Main' method is the entry point of an executable program.
4
-
ms.date: 06/23/2025
4
+
ms.date: 12/15/2025
5
5
f1_keywords:
6
6
- "main_CSharpKeyword"
7
7
- "Main"
@@ -14,27 +14,27 @@ helpviewer_keywords:
14
14
---
15
15
# Main() and command-line arguments
16
16
17
-
The `Main` method is the entry point of a C# application. When the application is started, the `Main` method is the first method that is invoked.
17
+
The runtime calls the `Main` method when you start a C# application. The `Main` method is the entry point of a C# application.
18
18
19
-
There can only be one entry point in a C# program. If you have more than one class that has a `Main` method, you must compile your program with the **StartupObject** compiler option to specify which `Main` method to use as the entry point. For more information, see [**StartupObject** (C# Compiler Options)](../../language-reference/compiler-options/advanced.md#startupobject). The following example displays the number of command line arguments as its first action:
19
+
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)](../../language-reference/compiler-options/advanced.md#startupobject). The following example displays the number of command line arguments as its first action:
You can also use top-level statements in one file as the entry point for your application. Just as the `Main` method, top-level statements can also [return values](#main-return-values) and access [command-line arguments](#command-line-arguments). For more information, see [Top-level statements](top-level-statements.md). The following example uses a `foreach` loop to display the command-line arguments using the `args` variable, and at the end of the program returns a success code (`0`):
23
+
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](#main-return-values) and access [command-line arguments](#command-line-arguments). For more information, see [Top-level statements](top-level-statements.md). 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`):
Beginning with C# 14, programs can be [*file-based apps*](./index.md#building-and-running-c-programs), where a single file contains the program. You run *file-based apps*with the command `dotnet run <file.cs>`, or using the `#!/usr/local/share/dotnet/dotnet run` directive as the first line (unix shells only).
27
+
Beginning with C# 14, programs can be [*file-based apps*](./index.md#building-and-running-c-programs), 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).
28
28
29
29
## Overview
30
30
31
-
- The `Main` method is the entry point of an executable program; it's where the program control starts and ends.
32
-
-`Main` must be declared inside a class or struct. The enclosing `class` can be `static`.
31
+
- The `Main` method is the entry point of an executable program. It's where the program control starts and ends.
32
+
-You must declare `Main` inside a class or struct. The enclosing `class` can be `static`.
33
33
-`Main` must be [`static`](../../language-reference/keywords/static.md).
34
-
-`Main` can have any [access modifier](../../programming-guide/classes-and-structs/access-modifiers.md) (except `file`).
35
-
-`Main` can either have a `void`, `int`, `Task`, or `Task<int>` return type.
34
+
-`Main` can have any [access modifier](../../programming-guide/classes-and-structs/access-modifiers.md).
35
+
-`Main` can return `void`, `int`, `Task`, or `Task<int>`.
36
36
- If and only if `Main` returns a `Task` or `Task<int>`, the declaration of `Main` can include the [`async`](../../language-reference/keywords/async.md) modifier. This rule specifically excludes an `async void Main` method.
37
-
-The `Main` method can be declared with or without a `string[]` parameter that contains command-line arguments. When using Visual Studio to create Windows applications, you can add the parameter manually or else use the <xref:System.Environment.GetCommandLineArgs> 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 the `args` array, but it's the first element of the <xref:System.Environment.GetCommandLineArgs> method.
37
+
-You can declare the `Main` method with or without a `string[]` parameter that contains command-line arguments. When using Visual Studio to create Windows applications, you can add the parameter manually or else use the <xref:System.Environment.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 the `args` array, but it's the first element of the <xref:System.Environment.GetCommandLineArgs> method.
38
38
39
39
The following list shows the most common `Main` declarations:
The preceding examples don't specify an access modifier, so they're implicitly `private` by default. It's possible to specify any explicit access modifier.
52
+
The preceding examples don't specify an access modifier, so they're implicitly `private` by default. You can specify any explicit access modifier.
53
53
54
54
> [!TIP]
55
-
> The addition of `async` and `Task`, `Task<int>` return types simplifies program code when console applications need to start and `await` asynchronous operations in `Main`.
55
+
> 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`.
56
56
57
57
## Main() return values
58
58
@@ -86,13 +86,13 @@ Create a new application by running `dotnet new console`. Modify the `Main` meth
86
86
87
87
Remember to save this program as *MainReturnValTest.cs*.
88
88
89
-
When a program is executed in Windows, any value returned from the `Main` function is stored in an environment variable. This environment variable can be retrieved using `ERRORLEVEL` from a batch file, or `$LastExitCode` from PowerShell.
89
+
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.
90
90
91
-
You can build the application using the [dotnet CLI](../../../core/tools/dotnet.md)`dotnet build` command.
91
+
You can build the application by using the [dotnet CLI](../../../core/tools/dotnet.md)`dotnet build` command.
92
92
93
93
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.
94
94
95
-
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.
95
+
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.
96
96
97
97
```powershell
98
98
dotnet run
@@ -116,21 +116,21 @@ When you declare an `async` return value for `Main`, the compiler generates the
In both examplesmain body of the program is within the body of `AsyncConsoleWork()` method.
119
+
In both examples, the main body of the program is within the body of the`AsyncConsoleWork()` method.
120
120
121
121
An advantage of declaring `Main` as `async` is that the compiler always generates the correct code.
122
122
123
123
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:
124
124
125
-
-`static Task Main()` results in the compiler emitting the equivalent of `private static void $GeneratedMain() => Main().GetAwaiter().GetResult();`
126
-
-`static Task Main(string[])` results in the compiler emitting the equivalent of `private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();`
127
-
-`static Task<int> Main()` results in the compiler emitting the equivalent of `private static int $GeneratedMain() => Main().GetAwaiter().GetResult();`
128
-
-`static Task<int> Main(string[])` results in the compiler emitting the equivalent of `private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();`
125
+
-`static Task Main()` results in the compiler emitting the equivalent of `private static void $GeneratedMain() => Main().GetAwaiter().GetResult();`.
126
+
-`static Task Main(string[])` results in the compiler emitting the equivalent of `private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();`.
127
+
-`static Task<int> Main()` results in the compiler emitting the equivalent of `private static int $GeneratedMain() => Main().GetAwaiter().GetResult();`.
128
+
-`static Task<int> Main(string[])` results in the compiler emitting the equivalent of `private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();`.
129
129
130
130
> [!NOTE]
131
-
>If the examples used `async` modifier on the `Main` method, the compiler would generate the same code.
131
+
>If the examples use the `async` modifier on the `Main` method, the compiler generates the same code.
132
132
133
-
## Command-Line Arguments
133
+
## Command-line arguments
134
134
135
135
You can send arguments to the `Main` method by defining the method in one of the following ways:
136
136
@@ -141,7 +141,7 @@ You can send arguments to the `Main` method by defining the method in one of the
141
141
|`static async Task Main(string[] args)`| Uses `await` but doesn't return a value |
142
142
|`static async Task<int> Main(string[] args)`| Return a value and uses `await`|
143
143
144
-
If the arguments aren't used, you can omit `args` from the method declaration for slightly simpler code:
144
+
If you don't use the arguments, you can omit `args` from the method declaration for slightly simpler code:
@@ -153,7 +153,7 @@ If the arguments aren't used, you can omit `args` from the method declaration fo
153
153
> [!NOTE]
154
154
> You can also use <xref:System.Environment.CommandLine%2A?displayProperty=nameWithType> or <xref:System.Environment.GetCommandLineArgs%2A?displayProperty=nameWithType> 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.
155
155
156
-
The parameter of the `Main` method is a <xref:System.String> array that represents the command-line arguments. Usually you determine whether arguments exist by testing the `Length` property, for example:
156
+
The parameter of the `Main` method is a <xref:System.String> array that represents the command-line arguments. Usually, you determine whether arguments exist by testing the `Length` property, for example:
At the beginning of the `Main` method the program tests if input arguments weren't supplied comparing length of `args` argument to `0` and displays the help if no arguments are found.<br/>
195
-
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.<br/>
196
-
After factorial is calculated (stored in `result` variable of type `long`), the verbose result is printed depending on the `result` variable.
194
+
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.<br/>
195
+
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.<br/>
196
+
After factorial is calculated (stored in `result` variable of type `long`), the verbose result is printed depending on the `result` variable.
197
197
198
-
2. 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.
198
+
1. 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.
199
199
200
-
3. To compile the application, enter the following command:
201
-
202
-
`dotnet build`
203
-
204
-
If your application has no compilation errors, a binary file named *Factorial.dll* is created.
205
-
206
-
4. Enter the following command to calculate the factorial of 3:
207
-
208
-
`dotnet run -- 3`
209
-
210
-
5. If 3 is entered on command line as the program's argument, the output reads: `The factorial of 3 is 6.`
200
+
1. To compile the application, enter the following command:
201
+
202
+
`dotnet build`
203
+
204
+
If your application has no compilation errors, the build process creates a binary file named *Factorial.dll*.
205
+
206
+
1. Enter the following command to calculate the factorial of 3:
207
+
208
+
`dotnet run -- 3`
209
+
210
+
1. If you enter 3 on the command line as the program's argument, the output reads: `The factorial of 3 is 6.`
211
211
212
212
> [!NOTE]
213
-
> When running an application in Visual Studio, you can specify command-line arguments in the [Debug Page, Project Designer](/visualstudio/ide/reference/debug-page-project-designer).
213
+
> When running an application in Visual Studio, specify command-line arguments in the [Debug Page, Project Designer](/visualstudio/ide/reference/debug-page-project-designer).
Copy file name to clipboardExpand all lines: docs/csharp/language-reference/keywords/access-modifiers.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,29 +1,29 @@
1
1
---
2
2
description: "Access Modifiers - C# Reference"
3
3
title: "Access Modifiers"
4
-
ms.date: 09/15/2022
4
+
ms.date: 12/15/2025
5
5
helpviewer_keywords:
6
6
- "access modifiers [C#]"
7
7
---
8
-
# Access Modifiers (C# Reference)
8
+
# Access modifiers (C# reference)
9
9
10
-
Access modifiers are keywords used to specify the declared accessibility of a member or a type. This section introduces the five access modifiers:
10
+
Use access modifiers to specify the declared accessibility of a member or a type. This section introduces the four access modifiers:
11
11
12
12
-`public`
13
13
-`protected`
14
14
-`internal`
15
15
-`private`
16
-
-`file`
17
16
18
-
The following seven accessibility levels can be specified using the access modifiers:
17
+
By using these access modifiers, you can specify the following six accessibility levels:
19
18
20
-
-[`public`](public.md): Access isn't restricted.
19
+
-[`public`](public.md): No access restrictions.
21
20
-[`protected`](protected.md): Access is limited to the containing class or types derived from the containing class.
22
21
-[`internal`](internal.md): Access is limited to the current assembly.
23
22
-[`protected internal`](protected-internal.md): Access is limited to the current assembly or types derived from the containing class.
24
23
-[`private`](private.md): Access is limited to the containing type.
25
24
-[`private protected`](private-protected.md): Access is limited to the containing class or types derived from the containing class within the current assembly.
26
-
-[`file`](file.md): The declared type is only visible in the current source file. File scoped types are generally used for source generators.
25
+
26
+
In addition, a top-level (non-nested) type can use the [`file`](file.md) modifier. The declared type is only visible in the current source file. File scoped types are generally used for source generators. You can't combine the `file` modifier with any access modifier.
27
27
28
28
This section also introduces the following concepts:
0 commit comments