最上層陳述式 - 不含 Main 方法的程式

小提示

剛開始開發軟體嗎? 先從 入門 教學開始。 那些教學會使用頂層敘述,所以你已經熟悉基本概念。

在找 Main 方法替代方案嗎? 關於顯式方法方法,請參見 Main

在新應用程式中使用 頂層語句 。 透過使用頂層語句,你可以直接在檔案根部撰寫可執行程式碼。

以下是完整的 C# 程式 Program.cs 檔案:

Console.WriteLine("Hello World!");

當你使用 dotnet new console 建立新的終端機應用程式時,預設會使用頂層語句。 它們適用於任何規模的程式——從小型工具和 Azure Functions 到完整應用程式皆適用。 如果你已有使用明確 Main 方法的應用程式,就不需要轉換。 兩種風格都能編譯成等效程式碼。

下列各節說明有關您可以使用最上層陳述式來做什麼和不能做什麼的規則。

入場點規則

應用程式必須只有一個進入點。 一個專案只能有一個頂層陳述的檔案,但它可以有任意數量的原始碼檔案,這些檔案沒有頂層陳述。 你可以明確寫一個 Main 方法,但它不能作為入門點。 在有頂層語句的專案中,即使專案有一個或多個-main方法,你也不能使用Main編譯器選項來選擇入口點。

對於含有最上層陳述式的專案,編譯器會產生一個方法作為程式的進入點。 該方法的簽名取決於最上層陳述式是否包含 await 關鍵字或 return 陳述式。 下表展示了方法簽名的樣貌,並使用表格中的方法名稱 Main 以便於方便。

最上層程式碼包含 隱含 Main 簽名
awaitreturn static async Task<int> Main(string[] args)
await static async Task Main(string[] args)
return static int Main(string[] args)
沒有 awaitreturn static void Main(string[] args)

從 C# 14 開始,程式可以是 基於檔案的應用程式,其中單一檔案包含該程式。 你可以透過指令執行dotnet <file.cs>,或直接在 Unix 上使用檔名(例如,./file.cs)來執行。 後者需要將 #!/usr/bin/env dotnet 指令列為第一行,並設定執行權限(chmod +x <file>)。

using 指令

對於包含頂層語句的單一檔案, using 指令必須放在該檔案的首位,如下範例所示:

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;

命名空間和類型定義

最上層陳述式會隱含地位於全域命名空間中。 具有最上層陳述式的檔案也可以包含命名空間和類型定義,但它們必須位於最上層陳述式之後。 例如:

MyClass.TestMethod();
MyNamespace.MyClass.MyMethod();

public class MyClass
{
    public static void TestMethod()
    {
        Console.WriteLine("Hello World!");
    }
}

namespace MyNamespace
{
    class MyClass
    {
        public static void MyMethod()
        {
            Console.WriteLine("Hello World from MyNamespace.MyClass.MyMethod!");
        }
    }
}

args

頂層語句可以參考變 args 數,存取應用程式啟動時傳遞給命令列的任何參數。 args變數永遠不是 null,但如果沒有提供命令列參數,則Length為 0。 例如:

if (args.Length > 0)
{
    foreach (var arg in args)
    {
        Console.WriteLine($"Argument={arg}");
    }
}
else
{
    Console.WriteLine("No arguments");
}

await 及退出碼

await 來呼叫非同步方法。 當你的頂層程式碼包含 await時,編譯器會產生一個回傳 Task的入口點。 執行時會監控該 Task 程序是否完成,並保持程序存活直到所有非同步工作結束。 例如:

Console.Write("Hello ");
await Task.Delay(5000);
Console.WriteLine("World!");

若要在應用程式結束時回傳退出碼,請使用該 return 語句。 編譯器會產生一個入口點,當你的程式碼同時包含 Task<int>await 時回傳 return;或只包含 int 時回傳 return。 例如:

string? s = Console.ReadLine();

int returnValue = int.Parse(s ?? "-1");
return returnValue;