はじめに
普段はVisual Studioを使って開発しているが、Visual Studio Codeでも開発できるようにしようと思い、開発環境を整えて遊んでいる。
で、最初に出来上がったProgram.csをコピーし、Program2.csを作成したところタイトルのエラー
トップレベルのステートメントを持つことができるのは、1 つのコンパイル ユニットのみです。
が発生した。
それぞれ記載内容は以下の通り。
Console.WriteLine("あああHello, World!");
Console.WriteLine("あいうえおHello, World!");
開発環境
Windows11
Visual Studio Code ・・・ .Net Install Tool, C#, Japanese Language Pack for Visual Studio Code をインストール済
トップレベルのステートメントって何?
簡単に言うと、class や static void Main() などの枠組みを書かず、ファイルの先頭から直接書く処理のこと。
Program.csもProgram2.csも、ファイルの中には1行目にいきなりログ出力の処理が記載されているので、トップレベルのステートメントを書いていると言える。
トップレベルステートメントを書くと、コンパイラはビルド時に「見えないクラスとMainメソッド」を自動生成し、その中に本来記載されたコードを押し込み、下記の状態になる。↓
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("あああHello, World!"); //←この行以外が付け足される
}
}
}
namespace MyApp
{
class Program2
{
static void Main(string[] args)
{
Console.WriteLine("あいうえおHello, World!"); //←この行以外が付け足される
}
}
}
この時点でなんとなく見えてくるが、両方のファイルにMainメソッドを書いている状態になる。
つまり、プログラムの開始地点が複数存在してしまい、どこから動かせばいいか判断できない状態になるため、エラーとなる。
こんなエラーが出る。まあ、デバッグ実行を強行したら動いたんだけども…
コンパイル ユニットって何?
1つのソースコードファイル(.csファイル)のこと。今回はProgram.csとProgram2.csの2ファイルあるため、コンパイルユニットは2つとなる。
※自分は実際の現場でこの単語は聞いたことがない。だいたい「ソースファイル」「csファイル」等の呼び方をするし、そう聞く。
解決策
片方の記述を枠組みのある形式に変更し、トップレベルのステートメントが1つになるようにする。今回はProgram2.csを修正。namespace MyApp
{
class Program2
{
static void log2() //←「void」以降のメソッド名を変更
{
Console.WriteLine("あいうえおHello, World!");
}
}
}
こうすることで、ビルド→プログラム実行した際はProgram.csに書いてある処理が実行される。解決。
Program2.csに書いてある処理を実行したければ、Program.cs内で呼べばオッケー。
終わりに
個人的には、保守性やコードの綺麗さの観点からこの記述方法はおすすめはしない。パッと見だと簡潔な書き方なのでプログラムの超基本(順次・分岐・繰り返し)を学ぶ際はこれで良いが、実際にさあアプリを作るぞってなったタイミングでstatic void Main(string[] args)のような記載にしたほうが良い。
無理矢理動かしたら動いた理由とか、解決する中で別の警告も出たので、次はその辺の記事も書く予定。

