ヘッダー
Visual Studio Tips集
 

C# 最上位レベルのステートメントを適用/解除する

2022/10/9

この記事が対象とする製品・バージョン

Visual Studio 2022 Visual Studio 2022 対象です。ただし、バージョン 17.3 (2022年8月9日)以降
VS2019 Visual Studio 2019 対象外ですが、参考にはなります。
VS2017 Visual Studio 2017 × 対象外です。
VS2015 Visual Studio 2015 × 対象外です。
VS2013 Visual Studio 2013 × 対象外です。
VS2012 Visual Studio 2012 × 対象外です。
VS2010 Visual Studio 2010 × 対象外です。
VS2008 Visual Studio 2008 × 対象外です。
VS2005 Visual Studio 2005 × 対象外です。
VS.NET 2003 Visual Studio 2003 × 対象外です。
VS.NET 2002 Visual Studio (2002) × 対象外です。
  Visual Studio Code × 対象外です。

 

 

最上位レベルのステートメントを解除する

最上位レベルステートメントとなっているものを解除して、Mainメソッド形式に変更するには、クイックアクション(ドライバーアイコン)を利用するのが簡単です。

このあと、プログラムの internal class Program の1行上に namespace ConsoleApp1; のように 「namespace プロジェクト名;」 を付けます。(後のセミコロン ; にご注意ください。)

このnamespaceの記述は不要な場合もあります。付けても害はないはずなので、判断に迷うなら付けておくとよいと思います。

 

 

 

最上位レベルのステートメントに変更する

Mainメソッド形式から最上位レベルステートメント形式に変更するには、クイックアクション(電球アイコン)を利用するのが簡単です。

※Mainメソッドに属性が付いている場合は、最上位レベルステートメントに変更できません。属性の有無はMainの前に [ ] 付きの記述があるかでわかります。よくあるのは[STAThread]属性です。

※同じ操作をしても「最上位レベルのステートメントに変換する」のクイックアクションが表示されない場合もあるようです。「Main」をクリックしてAlt + Enter で表示される電球アイコンをクリックするか、ファイルを開きなおすなどすると表示される確率が高いようです。

 

 

 

プロジェクト作成時に最上位レベルのステートメントを使用するか選択する

コンソールアプリや ASP.NET Core Webアプリでは プロジェクト作成時に 最上位レベルステートメント形式 を使用するか選択できます。

英語で「Do not use top-level statements」と表示されている場合もあります。

※このスクリーンショットは少し画像を切り貼りして実際のよりサイズを小さくしています。(本物はもっと余白が広いです。)

 

 

参考:自分でプログラムを編集して最上位レベルステートメントを適用/解除する

自分でプログラムを入力したり削除することで最上位レベルステートメントの有無を切り替えることもできます。ただし、いくつかパターンかあり、どのような場合でも通用する1つのやり方というものはありません。

基本的には、下記のサンプルの赤い部分を削除すると、最上位レベルのステートメントになり、赤い部分を付けるとMain形式のステートメントになります。

namespace ConsoleApp1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            //現在の日付を和暦で表示
            var Japanese = new System.Globalization.CultureInfo("ja-JP");
            Japanese.DateTimeFormat.Calendar = new System.Globalization.JapaneseCalendar();

            //例 「今 令和3年10月9日 です。」
            string wareki = DateTime.Now.ToString("今 ggy年M月d日 です。", Japanese);

            Console.WriteLine(wareki);
        }
    }
}

場合によって変わるのは次のようなケースです。(私が思いつくものをすべて列挙しますが完全ではないかもしれません。)

Visual Studioのクイックアクションによる変換ではこのあたりのことをほどんと考慮してくれるので、よくわからない場合は、クイックアクションを使用して変換するのが良いです。

  • 最上位レベルのステートメントで return を使用している場合、Mainの定義は void ではなく、int になります。さらに await も使用している場合は Task<int> になります。
  • Mainメソッド内で、Mainメソッドが定義されている名前空間(よくあるのはConsoleApp1)と同じ名前空間のクラスや構造体などを名前空間を省略して呼び出している場合、赤字の部分を単純に消すとその呼び出しは動作しなくなります。この場合表示される生成されるエラーは「エラー CS0103 現在のコンテキストに 'Class1' という名前は存在しません」のようなものです。これを解消するには、赤い部分を削除した後に、プログラムの先頭の方に namespace ConsoleApp1; のように名前空間の定義を追加します。または using ConsoleApp1; のように省略されている名前空間の候補を定義します。
  • Mainメソッドに属性が付いている場合は、最上位レベルステートメントにできません。属性の有無は Main メソッドの前に [ ] 付きの記述があるかで区別できます。よくあるのは [STAThread] 属性です。
  • 最上位レベルのステートメントで await を使用している場合、Mainの定義で static の後に async を付ける必要があります。
  • namespace ConsoleApp1 の部分は、使用している名前空間により変わります。既定ではプロジェクト名が名前空間になります。

 

 

参考:ドキュメント

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

C# 9.0 の新機能 - C# ガイド | Microsoft Learn

.NET 6 での C# コンソール アプリ テンプレートの変更 - .NET | Microsoft Learn