LoginSignup
3
3

More than 1 year has passed since last update.

[雑記] エントリーポイント(C#)

Posted at

エントリーポイント

実行可能(Exe形式等)なプログラムを書く際、最初に実行される処理を エントリーポイント と呼ぶ。
C# においては、以下の方法で エントリーポイント を定義できる。

  • 特定の条件を満たした Main メソッド

  • トップレベルステートメント (C# 9.0 以降)

Main メソッド

C# では、以下の条件を全て満たすメソッドを エントリーポイント として指定できる(以下 "Main メソッド" と表記)。

  • メソッド名が Main
  • 静的メソッド (static)
  • 引数は なし または string[] のどちらか
  • 戻り値は以下のいずれか
    • なし (void)
    • int
    • Task (C# 7.1以降)
    • Task<int> (C# 7.1以降)

その他、細々としたこと。

  • クラス名は任意で、publicにする必要は無い (internal でもエントリーポイントに指定できる)
  • Main メソッド は public にする必要は無い (アクセス修飾子は private や 未指定 でも良い)
  • Main メソッド の引数として string[] を指定した場合、実行時のコマンドライン引数を string配列 として受け取れる
  • Main メソッド の戻り値の型が Task または Task<int> の場合、async 修飾子を付与して 非同期メソッド にできる

Main メソッド の例

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

エントリーポイントの指定

スタートアップオブジェクト に指定されたクラスの Main メソッド がエントリーポイントとして指定される。
プロジェクト(アセンブリ) に含まれる Main メソッド の個数により、スタートアップオブジェクト は以下の通り指定される。

  • Main メソッド が存在しない場合
    • ビルドエラー(実行不可)
  • Main メソッド が 1つのクラスにのみ 存在する場合
    • Main メソッド が含まれるクラスが スタートアップオブジェクト として暗黙的に指定される
  • Main メソッド が 複数のクラス に存在する場合
    • 明示的に スタートアップオブジェクト を指定する必要がある
      • ビルドオプション(-main)
      • プロジェクト定義(csprojファイル の StartupObject タグ)
    • 指定が無い場合、ビルドエラー(実行不可)

なお、スタートアップオブジェクト に指定されたクラスに Main メソッド が複数存在する場合、エントリーポイントとして扱うメソッドが特定できない為ビルドエラーとなる。

トップレベルステートメント

C# 9.0 で導入された、トップレベル に書かれた ステートメント を エントリーポイント として扱う仕組み。
トップレベルステートメント は プロジェクトの他のプログラムから実行することは出来ない為、エントリーポイント としてのみ取り扱われる(誤ってプログラム内で エントリーポイント を実行することを防ぐことができる)。

トップレベルステートメント は以下の制約がある。

  • プロジェクト(アセンブリ) 全体 で 1つのファイル にのみ、記述できる
  • ファイル中の 名前空間 や クラス等 の定義より上にのみ記述できる(基本的にファイルの先頭に記述)

その他、細々としたこと。

  • コマンドライン引数が必要な場合、暗黙的に定義される args という名前の変数で参照できる
    • Main メソッド の引数で string[] args と定義した場合に相当する
    • コマンドライン引数が入力されなかった場合、args は 長さ 0 の配列になる(nullにはならない)
  • int 値 を返すことが出来る
    • Main メソッド における戻り値の型を int とした場合に相当する
    • int 値 を返さないルートがある場合、ビルドエラーになる(メソッドの場合と同様)
      例) 以下のコードはビルドエラー
      if (args.Length == 0)
      {
          return 1;
      }
      Console.WriteLine($"Hello, World! {args[0]}");
      
  • await を使用して 非同期メソッド を呼び出すことが出来る
    • Main メソッド における戻り値の型を Task または Task<int> とした場合に相当する
  • Main メソッド と併用できない
    • トップレベルステートメント が存在するプロジェクトで Main メソッド を定義した場合、無視される。
      ビルド時に以下の警告が出力される。

      CS7022 プログラムのエントリ ポイントは、グローバル コードです。エントリ ポイント 'Program.Main()' を無視します。

    • トップレベルステートメント が存在するプロジェクトで スタートアップオブジェクト を指定した場合、ビルドエラーとなる。

      CS8804 トップレベルのステートメントを含むコンパイル ユニットがある場合、/main を指定することはできません。

  • C# 10 では、ビルド時に トップレベルステートメント が暗黙的に作成された Program クラスに展開される為、グローバル(名前空間を指定しない) で Program クラスを宣言するとビルドエラーになる(クラス名が競合する)。
    • partial を付与することでビルドエラーは回避できる。

トップレベルステートメント の例

using System;

Console.WriteLine("Hello, World!");
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3