Main() 和命令列引數
Main
方法是 C# 應用程式的進入點。 (程式庫和服務不需要方法 Main
作為進入點。啟動應用程式時, Main
方法是叫用的第一個方法。
C# 程式中只能有一個進入點。 如果您有一個以上的類別具有 Main
方法,則必須使用 StartupObject 編譯器選項編譯器,以指定要 Main
作為進入點的方法。 如需詳細資訊,請參閱 StartupObject (C# 編譯器選項)。
class TestClass
{
static void Main(string[] args)
{
// Display the number of command line arguments.
Console.WriteLine(args.Length);
}
}
您也可以在 一個檔案中使用最上層語句 作為應用程式的進入點:
using System.Text;
StringBuilder builder = new();
builder.AppendLine("Hello");
builder.AppendLine("World!");
Console.WriteLine(builder.ToString());
概觀
Main
方法是可執行程式的進入點;它是程式控制開始和結束的位置。Main
會宣告於類別或結構內部。Main
必須是static
,而且不需要public
為 。 (在先前的範例中,它會接收 的預設存取private
權。)封入類別或結構不需要是靜態的。Main
可以有void
、、int
Task
或Task<int>
傳回型別。- 只有當
Main
傳回Task
或Task<int>
時,Main
的宣告才可以包含async
修飾詞。 這特別排除方法async void Main
。 Main
方法不一定要使用包含命令列引數的string[]
參數來宣告。 使用 Visual Studio 建立 Windows 應用程式時,您可以手動新增 參數,或使用 GetCommandLineArgs() 方法來取得命令列引數。 參數會讀入來做為以零為基礎的命令列引數。 不同于 C 和 C++,程式的名稱不會被視為陣列中的args
第一個命令列引數,但它是 方法的第一個元素 GetCommandLineArgs() 。
下列清單顯示有效的 Main
簽章:
public static void Main() { }
public static int Main() { }
public static void Main(string[] args) { }
public static int Main(string[] args) { }
public static async Task Main() { }
public static async Task<int> Main() { }
public static async Task Main(string[] args) { }
public static async Task<int> Main(string[] args) { }
上述範例全都使用 public
存取子修飾詞。 這是典型的,但並非必要。
當主控台應用程式必須啟動且等待 Main
中的 await
非同步作業時,新增的 async
與 Task
、Task<int>
傳回型別可簡化程式碼。
Main() 傳回值
您可以透過下列其中一種方式定義 方法,從 Main
方法傳回 int
:
Main 方法程式碼 |
Main 簽名 |
---|---|
args 不使用 或await |
static int Main() |
使用 args ,不使用 await |
static int Main(string[] args) |
args 不使用 、 使用await |
static async Task<int> Main() |
使用 args 和 await |
static async Task<int> Main(string[] args) |
如果未使用 來自 Main
的傳回值,則傳 void
回 或 Task
允許稍微簡單的程式碼。
Main 方法程式碼 |
Main 簽名 |
---|---|
args 不使用 或await |
static void Main() |
使用 args ,不使用 await |
static void Main(string[] args) |
args 不使用 、 使用await |
static async Task Main() |
使用 args 和 await |
static async Task Main(string[] args) |
不過,傳 int
回 或 Task<int>
可讓程式將狀態資訊傳達給叫用可執行檔的其他程式或腳本。
下列範例示範如何存取進程的結束代碼。
此範例使用 .NET Core 命令列工具。 如果您不熟悉 .NET Core 命令列工具,您可以在此 入門文章 中瞭解它們。
執行 dotnet new console
來建立新的應用程式。 Main
修改 Program.cs 中的 方法,如下所示:
// Save this program as MainReturnValTest.cs.
class MainReturnValTest
{
static int Main()
{
//...
return 0;
}
}
在 Windows 中執行程式時,任何從 Main
函式傳回的值,皆會儲存在環境變數中。 您可以從批次檔或 $LastExitCode
PowerShell 擷 ERRORLEVEL
取此環境變數。
您可以使用 dotnet CLIdotnet build
命令來建置應用程式。
接下來,建立 PowerShell 腳本以執行應用程式並顯示結果。 將下列程式碼貼入文字檔,將它儲存為 test.ps1
,並放到包含專案的資料夾中。 在 PowerShell 提示字元中輸入 test.ps1
,以執行 PowerShell 腳本。
由於程式碼會傳回零,因為批次檔會報告成功。 不過,如果您將 MainReturnValTest.cs 變更為傳回非零值,然後重新編譯程式,則後續的 PowerShell 腳本執行將會回報失敗。
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 傳回值
當您宣告 的 async
傳回值 Main
時,編譯器會產生重複使用的程式碼,以在 中 Main
呼叫非同步方法。 如果您未指定 async
關鍵字,則必須自行撰寫該程式碼,如下列範例所示。 此範例中的程式碼可確保您的程式會執行,直到非同步作業完成為止:
class AsyncMainReturnValTest
{
public static void Main()
{
AsyncConsoleWork().GetAwaiter().GetResult();
}
private static async Task<int> AsyncConsoleWork()
{
// Main body here
return 0;
}
}
此未定案程式碼可以取代為:
class Program
{
static async Task<int> Main(string[] args)
{
return await AsyncConsoleWork();
}
private static async Task<int> AsyncConsoleWork()
{
// main body here
return 0;
}
}
宣告 Main
為 async
的優點是編譯器一律會產生正確的程式碼。
當應用程式進入點傳回 Task
或 Task<int>
時,編譯器會產生新的進入點,以呼叫應用程式程式碼中宣告的進入點方法。 假設此進入點稱為 $GeneratedMain
,編譯器會為這些進入點產生下列程式碼:
static Task Main()
會導致編譯器發出private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
的對等項目static Task Main(string[])
會導致編譯器發出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(string[])
會導致編譯器發出private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
的對等項目
注意
如果這些範例在 Main
方法上使用 async
修飾詞,編譯器會產生相同的程式碼。
命令列引數
您可以使用下列其中一種方式,透過定義方法以將引數傳送給 Main
方法:
Main 方法程式碼 |
Main 簽名 |
---|---|
沒有傳回值,不使用 await |
static void Main(string[] args) |
傳回值,不使用 await |
static int Main(string[] args) |
沒有傳回值,使用 await |
static async Task Main(string[] args) |
傳回值,使用 await |
static async Task<int> Main(string[] args) |
如果未使用引數,您可以從方法簽章中省略 args
稍微簡單一點的程式碼:
Main 方法程式碼 |
Main 簽名 |
---|---|
沒有傳回值,不使用 await |
static void Main() |
傳回值,不使用 await |
static int Main() |
沒有傳回值,使用 await |
static async Task Main() |
傳回值,使用 await |
static async Task<int> Main() |
注意
您也可以使用 Environment.CommandLine 或 Environment.GetCommandLineArgs ,從主控台或 Windows Forms 應用程式中的任何點存取命令列引數。 若要在 Windows Forms 應用程式中的方法簽章中 Main
啟用命令列引數,您必須手動修改 的 Main
簽章。 Windows Forms 設計工具所產生的程式碼會 Main
建立,而不需要輸入參數。
Main
方法的參數是代表命令列引數的 String 陣列。 您通常會透過測試 Length
屬性來決定引數是否存在,例如:
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
return 1;
}
提示
args
陣列不能是 Null。 因此,在沒有 Null 檢查的情況下存取 Length
屬性是安全的。
您也可以使用 Convert 類別或 Parse
方法,將字串引數轉換為數字類型。 例如,下列陳述式將使用 Parse 方法,以將 string
轉換為 long
數字:
long num = Int64.Parse(args[0]);
也可能使用別名為 Int64
的 C# 類型 long
:
long num = long.Parse(args[0]);
您還可以使用 Convert
類別方法 ToInt64
執行相同作業:
long num = Convert.ToInt64(s);
下列範例示範如何在主控台應用程式中使用命令列引數。 應用程式會在執行階段接受一個引數,並將引數轉換為整數,以及計算數字的階乘。 如果未提供任何引數,則應用程式會發出說明程式正確用法的訊息。
若要從命令提示字元編譯和執行應用程式,請遵循下列步驟︰
將下列程式碼貼到任何文字編輯器中,然後將檔案儲存為名稱為 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) { // Test if input arguments were supplied. if (args.Length == 0) { Console.WriteLine("Please enter a numeric argument."); Console.WriteLine("Usage: Factorial <num>"); return 1; } // Try to convert the input arguments to numbers. This will throw // an exception if the argument is not a number. // num = int.Parse(args[0]); 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; } // Calculate factorial. long result = Functions.Factorial(num); // Print result. if (result == -1) Console.WriteLine("Input must be >= 0 and <= 20."); else Console.WriteLine($"The Factorial of {num} is {result}."); return 0; } } // If 3 is entered on command line, the // output reads: The factorial of 3 is 6.
從 [開始] 畫面或 [ 開始 ] 功能表,開啟 Visual Studio 開發人員命令提示 字元視窗,然後流覽至包含您所建立檔案的資料夾。
輸入下列命令以編譯應用程式。
dotnet build
如果您的應用程式沒有編譯錯誤,則會建立名為 Factorial.exe 的可執行檔。
輸入下列命令以計算 3 的階乘:
dotnet run -- 3
命令會產生以下輸出:
The factorial of 3 is 6.
注意
在 Visual Studio 中執行應用程式時,您可以在專案設計工具、偵錯頁中指定命令列引數。
C# 語言規格
如需詳細資訊,請參閱<C# 語言規格>。 語言規格是 C# 語法及用法的限定來源。
另請參閱
意見反應
提交並檢視相關的意見反應