最上位レベルのステートメント - Main
メソッドを使用しないプログラム
コンソール アプリケーション プロジェクトに Main
メソッドを明示的に含める必要はありません。 代わりに、"最上位レベルのステートメント" 機能を使用し、記述しなければならないコードを最小限に抑えることができます。
最上位レベルのステートメントを使用すると、実行可能コードをファイルのルートに直接記述できるため、クラスまたはメソッドでコードをラップする必要がなくなります。
つまり、Program
クラスと Main
メソッドの形式を使わずにプログラムを作成できます。
この場合、アプリケーションに対し、コンパイラで、メソッド エントリ ポイントを含む Program
クラスが生成されます。 生成されたメソッドの名前は Main
ではありません。これは、コードで直接参照できない実装の詳細です。
完全な C# プログラムである Program.cs ファイルを次に示します。
Console.WriteLine("Hello World!");
最上位レベルのステートメントでは、Azure Functions や GitHub Actions など、小さなユーティリティのために簡単なプログラムを記述できます。 また、C# プログラムを始めたばかりの方にとってコードを習い、書くことがもっと簡単になります。
次のセクションでは、最上位レベルのステートメントでできることとできないことに関する規則について説明します。
最上位レベルのファイルは 1 つだけ
アプリケーションに含めるエントリ ポイントは 1 つだけとする必要があります。 プロジェクトには、最上位のステートメントを含むファイルを 1 つだけ含めることができます。 1 つのプロジェクトで複数のファイルに最上位レベルのステートメントを置くと、次のコンパイラ エラーが発生します。
CS8802 トップレベルのステートメントを持つことができるのは、1 つのコンパイル ユニットのみです。
プロジェクトには、最上位レベルのステートメントを持たない任意の数のソース コード ファイルを含めることができます。
エントリ ポイントは他に用意しない
Main
メソッドは明示的に記述できますが、エントリ ポイントとして機能させることができません。 コンパイラから次の警告が出ます。
CS7022 プログラムのエントリ ポイントは、グローバル コードです。エントリ ポイント 'Main()' を無視します。
最上位レベルのステートメントが含まれるプロジェクトでは、そのプロジェクトに メソッドが複数含まれる場合でも、Main
コンパイラ オプションを使用してエントリ ポイントを選択することができません。
using
ディレクティブ
using
ディレクティブを含める場合、それらは次の例のようにファイルの先頭に置く必要があります。
using System.Text;
StringBuilder builder = new();
builder.AppendLine("The following arguments are passed:");
// Display the command line arguments using the args variable.
foreach (var arg in args)
{
builder.AppendLine($"Argument={arg}");
}
Console.WriteLine(builder.ToString());
// Return a success code.
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
は、コマンドライン引数が指定されなかった場合、ゼロになります。 次に例を示します。
if (args.Length > 0)
{
foreach (var arg in args)
{
Console.WriteLine($"Argument={arg}");
}
}
else
{
Console.WriteLine("No arguments");
}
await
await
を使用して非同期メソッドを呼び出すことができます。 次に例を示します。
Console.Write("Hello ");
await Task.Delay(5000);
Console.WriteLine("World!");
プロセスの終了コード
アプリケーションの終了時に int
値を返すには、return
を返す Main
メソッドの場合と同じように、int
ステートメントを使用します。 次に例を示します。
string? s = Console.ReadLine();
int returnValue = int.Parse(s ?? "-1");
return returnValue;
暗黙的なエントリ ポイント メソッド
最上位レベルのステートメントが含まれるプロジェクトに対して、プログラムのエントリ ポイントとして機能するメソッドがコンパイラによって生成されます。 メソッドのシグネチャは、最上位レベルのステートメントに 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) |
await も return もない |
static void Main(string[] args) |
C# 言語仕様
詳細については、「C# 言語の仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。
.NET