Main() とコマンド ライン引数
Main
メソッドは、C# アプリケーションのエントリ ポイントです アプリケーションを起動すると、最初に Main
メソッドが呼び出されます。
C# プログラムのエントリ ポイントは 1 つのみです。 Main
メソッドを持つクラスが 2 つ以上ある場合、プログラムをコンパイルする際に StartupObject コンパイラ オプションを使用して、どの Main
メソッドをエントリ ポイントとして使用するかを指定する必要があります。 詳細については、「StartupObject (C# コンパイラ オプション)」を参照してください。
class TestClass
{
static void Main(string[] args)
{
// Display the number of command line arguments.
Console.WriteLine(args.Length);
}
}
アプリケーションのエントリ ポイントとして、1 つのファイル内で最上位レベルのステートメントを使用することもできます。
Main
メソッドと同様に、最上位レベルのステートメントも値を返し、コマンド ライン引数にアクセスできます。
詳しくは、「最上位レベルのステートメント」を参照してください。
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;
概要
Main
メソッドは実行可能プログラムのエントリ ポイントであり、ここでプログラムの制御を開始および終了します。Main
は、クラスまたは構造体の内部で宣言する必要があります。 外側のclass
はstatic
でもかまいません。Main
は、static
である必要があります。Main
は、(file
を除く) 任意のアクセス修飾子を持つことができます。Main
の戻り値は、void
、int
、Task
、Task<int>
のいずれかになります。Main
でTask
またはTask<int>
が返される場合に限り、Main
の宣言にasync
修飾子を含めることができます。 これにより、async void Main
メソッドが明確に除外されます。Main
メソッドを宣言する際、コマンドライン引数を含むstring[]
パラメーターは指定してもしなくてもかまいません。 Visual Studio を使用して Windows アプリケーションを作成する場合、このパラメーターを手動で追加するか GetCommandLineArgs() メソッドを使用して、コマンドライン引数を取得できます。 パラメーターは、インデックス 0 のコマンドライン引数として読み取られます。 C や C++ とは異なり、プログラムの名前は、GetCommandLineArgs() の最初の要素です。args
配列の最初のコマンドライン引数として扱われることはありません。
次の一覧は、最も一般的な Main
宣言を示したものです。
static void Main() { }
static int Main() { }
static void Main(string[] args) { }
static int Main(string[] args) { }
static async Task Main() { }
static async Task<int> Main() { }
static async Task Main(string[] args) { }
static async Task<int> Main(string[] args) { }
上記の例ではアクセス修飾子を指定していないため、既定で暗黙的に private
に設定されます。 これはよく行われますが、明示的なアクセス修飾子を指定することもできます。
ヒント
コンソール アプリケーションの Main
で await
を使用して非同期操作を開始する必要がある場合、戻り値の型 async
、Task
、Task<int>
を追加することでプログラム コードを簡略化できます。
Main() の戻り値
次のいずれかの方法でメソッドを定義することで、Main
メソッドから int
を返すことができます。
Main 宣言 |
Main メソッド コード |
---|---|
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) |
args と await を使用する |
Main
からの戻り値を使用しない場合、void
か Task
を返すと少し簡単なコードにすることができます。
Main 宣言 |
Main メソッド コード |
---|---|
static void Main() |
args と await は使用しない |
static void Main(string[] args) |
args を使用し、await を使用しない |
static async Task Main() |
args を使用せず、await を使用する |
static async Task Main(string[] args) |
args と await を使用する |
ただし、int
か Task<int>
を返すことによって、プログラムが状態の情報を、実行可能ファイルを呼び出す他のプログラムまたはスクリプトに伝達することができます。
次の例からは、プロセスの終了コードにアクセスする方法がわかります。
この例では、.NET Core コマンドライン ツールを使用します。 .NET Core コマンドライン ツールに慣れていない場合は、この概要の記事を参照してください。
dotnet new console
を実行して新しいアプリケーションを作成します。 program.cs の Main
メソッドを次のように変更します。
// Save this program as MainReturnValTest.cs.
class MainReturnValTest
{
static int Main()
{
//...
return 0;
}
}
プログラムを Windows で実行する場合、Main
関数からの戻り値はすべて 1 つの環境変数に格納されます。 この環境変数を取得するには、バッチ ファイルから ERRORLEVEL
を使用するか、PowerShell から $LastExitCode
を使用します。
dotnet CLI の dotnet build
コマンドを使用してアプリケーションを構築できます。
次に、アプリケーションを実行して結果を表示する PowerShell スクリプトを作成します。 次のコードをテキスト ファイルに貼り付け、プロジェクトが保存されているフォルダーに test.ps1
として保存します。 PowerShell プロンプトに「test.ps1
」と入力して PowerShell スクリプトを実行します。
コードがゼロを返すため、バッチ ファイルで成功が報告されます。 ただし、MainReturnValTest.cs が 0 以外の値を返すように変更して、プログラムを再コンパイルする場合、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
非同期 Main の戻り値
Main
で async
戻り値を宣言すると、Main
内で非同期メソッドを呼び出すための定型コードがコンパイラによって生成されます。 async
キーワードを指定しない場合は、次の例に示すように、そのコードを自分で記述する必要があります。 この例のコードでは、非同期操作が完了するまでプログラムが確実に実行されるようにしています。
class AsyncMainReturnValTest
{
public static int Main()
{
return 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 メソッド コード |
---|---|
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) |
戻り値があり、await を使用する |
引数が使用されない場合、以下のようにメソッド宣言から args
を省略することでコードが少し単純になります。
Main 宣言 |
Main メソッド コード |
---|---|
static void Main() |
戻り値がなく、await を使用しない |
static int Main() |
戻り値があり、await を使用しない |
static async Task Main() |
戻り値がなく、await を使用する |
static async Task<int> Main() |
戻り値があり、await を使用する |
注意
Environment.CommandLine または Environment.GetCommandLineArgs を使用して、コンソールまたは Windows フォーム アプリケーション内の任意の場所からコマンド ライン引数にアクセスすることもできます。 Windows フォーム アプリケーションの Main
メソッド宣言でコマンド ライン引数を有効にするには、Main
の宣言を手動で変更する必要があります。 Windows フォーム デザイナーが生成するコードで作成されるのは、入力パラメーターなしの Main
です。
Main
メソッドのパラメーターは String の配列で、コマンド ライン引数を表しています。 通常は、Length
プロパティを調べて引数があるかどうかを確認します。次はその例です。
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
return 1;
}
ヒント
args
配列を null にすることはできません。 そのため、null チェックを行わずに Length
プロパティに安全にアクセスできます。
また、Convert クラスまたは Parse
メソッドを使って、文字列型の引数を数値型に変換できます。 たとえば、次のステートメントでは、string
メソッドを使用して long
を Parse 値に変換します。
long num = Int64.Parse(args[0]);
C# の long
型を使うこともできます。これは Int64
のエイリアスです。
long num = long.Parse(args[0]);
また、同じ変換に Convert
クラスの ToInt64
メソッドを使うこともできます。
long num = Convert.ToInt64(s);
詳細については、次のトピックを参照してください。 Parse および Convert
ヒント
コマンド ライン引数の解析は複雑になることがあります。 プロセスを簡単にするため、System.CommandLine ライブラリ (現在ベータ版) の使用を検討してください。
コンソール アプリケーションでコマンド ライン引数を使用する方法の例を次に示します。 アプリケーションは、実行時に引数を 1 つ受け取り、整数に変換し、その値の階乗を計算しています。 引数がない場合は、アプリケーションの正しい使用方法を説明するメッセージを表示します。
コマンド プロンプトからアプリケーションをコンパイルして実行するには、次の手順を実行します。
次のコードをテキスト エディターに貼り付け、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# の構文と使用法に関する信頼性のある情報源です。
関連項目
.NET