次の方法で共有


最上位レベルのステートメント - Main メソッドを使用しないプログラム

ヒント

ソフトウェアの開発は初めてですか? 最初に、 作業の開始 に関するチュートリアルから始めます。 これらのチュートリアルでは最上位レベルのステートメントを使用するため、基本について既に理解しています。

代替の Main 方法をお探しですか? 明示的な メソッドのアプローチについては、Main メソッドのMainを参照してください。

新しいアプリには、トップレベルステートメントを使用しましょう。 最上位レベルのステートメントを使用すると、実行可能コードをファイルのルートに直接記述できます。

完全な C# プログラムである Program.cs ファイルを次に示します。

Console.WriteLine("Hello World!");

dotnet new consoleを使用して新しいコンソール アプリを作成すると、既定で最上位レベルのステートメントが使用されます。 小規模なユーティリティや Azure Functions から完全なアプリケーションまで、あらゆる規模のプログラムに適しています。 明示的な Main メソッドを使用する既存のアプリケーションがある場合は、変換する必要はありません。 どちらのスタイルも同等のコードにコンパイルされます。

次のセクションでは、最上位レベルのステートメントでできることとできないことに関する規則について説明します。

エントリーポイントルール

アプリケーションに含めるエントリ ポイントは 1 つだけとする必要があります。 プロジェクトには最上位レベルのステートメントを含むファイルを 1 つだけ含めることができますが、最上位レベルのステートメントを持たない任意の数のソース コード ファイルを含めることができます。 Main メソッドは明示的に記述できますが、エントリ ポイントとして機能することはできません。 最上位レベルのステートメントを含むプロジェクトでは、プロジェクトに 1 つ以上の-main メソッドがある場合でも、Main コンパイラ オプションを使用してエントリ ポイントを選択することはできません。

最上位レベルのステートメントが含まれるプロジェクトに対して、プログラムのエントリ ポイントとして機能するメソッドがコンパイラによって生成されます。 メソッドのシグネチャは、最上位レベルのステートメントに await キーワードか return ステートメントが含まれるかどうかによって決まります。 次の表は、便宜上、テーブル内のメソッド名 Main を使用して、メソッド シグネチャがどのように表示されるかを示しています。

最上位レベルのコードに含まれる 暗黙的 Main シグネチャ
await および return 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 以降では、1 つのファイルにプログラムが含まれるファイル ベースのアプリをプログラムにすることができます。 ファイル ベースのアプリは、コマンド dotnet <file.cs>を使用するか、Unix 上のファイル名 (./file.cs など) を直接使用して実行します。 後者では、最初の行として #!/usr/bin/env dotnet ディレクティブを含め、実行アクセス許可 (chmod +x <file>) を設定する必要があります。

using ディレクティブ

最上位レベルのステートメントを含む 1 つのファイルの場合、次の例のように、 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;