壁 その1 は、Main メソッドがないことです。
C#を勉強したとき、アプリを起動したときに最初に実行するメソッドとしてMainメソッドを定義すると習いました。
今回作成したWebアプリのプロジェクトに Program.cs というファイルがあって、このファイルがエントリーポイント、つまりプロジェクトを起動したときに最初に動作するプログラムになります。
Program クラス の Main メソッド が Webアプリケーションのエントリーポイント、つまりプロジェクトを起動したときに最初に動作するプログラムになります。
エントリーポイントには Main メソッド が必要なはずです。
チュートリアルのサンプルコードを見ると、下記例のコードの赤字で示すようにクラス名とMainメソッドが定義されているものがあります。
以下に Program.cs ファイルのコード例を示します。
using ContosoUniversity.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
namespace ContosoUniversity
{
public class Program ←Programクラス
{
public static void Main(string[] args) ←Mainメソッド
{
var host = CreateHostBuilder(args).Build();
~ 以下省略 ~
ところが、今回作成したプロジェクトの Program.cs には クラス名 の定義もなく、Main メソッド の定義もありません。
以下にクラス名と Main メソッド が定義されていない Program.cs ファイル のコード例を示します。
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ContosoUniversity.Data;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString(“SchoolContext”) ?? throw new InvalidOperationException(“Connection string ‘SchoolContext’ not found.”)));
~ 以下省略 ~
クラス名 の定義も Mainメ ソッド の定義もありません。
このコードを見て、どうしてなのだろう、と疑問が湧いてきました。
技術の習得と勉強のためのチュートリアルの実践です。
しっかりと 疑問の解決にも取り組んで、納得するまで 調べることにしました。
マイクロソフトのチュートリアルのサイトは、ASP.NET Core のバージョンごとにそれぞれチュートリアルがあります。
そこで、バージョンごとの Program.cs ファイルの中味をチェックしてみました。
ASP.NET Core 5.0 までの Program.csファイル には、 Programクラス とそのクラスに Mainメソッド が定義されています。
ところが、 ASP.NET Core 6.0 以降の Program.csファイル には Programクラス と Mainメソッド の定義がありません。
さらに調べてみると、C#9 以降は、コンソール アプリケーション プロジェクトに Main メソッド を明示的に含める必要がなくなったとのこと。
プロジェクトで最初に実行するプログラムを 最上位レベルのステートメント と呼び、 最上位レベルのステートメント は Main メソッドを定義しないことになりました。
つまり、 Mainメソッド を使用しないプログラムになったということです。
Mainメソッド の代わりに、”最上位レベルのステートメント” 機能を使用することで、記述しなければならないコードを最小限に抑えることができるとのこと。
最上位レベルのステートメント のコード は、コンパイラによってアプリケーションに対し、クラスと Main メソッド エントリーポイントが自動生成されるそうです。
そして、ASP.NET Core の 最上位レベルのステートメント は program.cs ファイルに記述する決まりです。
最上位レベルのステートメント には、次のルールがあります。
■最上位レベルのファイルは 1 つだけ
プロジェクトには、最上位のステートメント を含むファイルを 1 つだけ含めることができ、複数のファイルに 最上位レベルのステートメント を置くと、コンパイラ エラーが発生する。
■エントリ ポイントは他に用意しない
Main メソッド は明示的に記述できますが、エントリーポイント として機能させることができない。
(エントリーポイントとしてMainメソッドを記述しても無駄なのだ、と理解しました。)
■using ディレクティブ
using ディレクティブを含める場合、ファイル(Program.csファイル)の先頭に指定する必要がある。
■グローバル名前空間
最上位レベルのステートメント は暗黙的にグローバル名前空間に属します。
(グローバルでなければ エントリーポイント になれないので、これは当然のことだと理解しました。)
最上位レベルのステートメント 機能を使うことで、エントリーポイント を Program.cs ファイル と決め、さらに クラス名 や Mainメソッド を定義しなくてよくなったため、プログラマーが無駄に エントリーポイント を定義したり、二重定義のミスを防止したりできるようになったのかな、と思いました。
1つめの壁の答えは、マイクロソフトのページにありました。
でも、そこにたどり着くまで結構迷走しました。
こうして、なんとか、1つ目の壁はクリアしました。
余談ですが
今年は、とにかく暑い!
ここ横浜市は8月3日までに猛暑日が6日ありました。京都府では21日もあったそうです。
そして、猛暑はもうしばらく続く予報です。
温暖化 どうなっているんだ・・・という思いです。
7月以降、庭仕事は、早朝に庭の小さな菜園でできたナス、キュウリの収穫をすることと、朝と夕方に植木鉢の草花や菜園に水やりをするくらいです。涼しくなるまで本格的な庭仕事は休眠です。
涼しくなるまでは冷房のきいた部屋でプログラミングに精を出そうと思っています。