Visual Studio 2022 が昨年11月にリリースされ、C#も10.0になりました。
毎日レガシーコード満載のプロジェクトと戦っている勇者さんたちも、「もう春だし、そろそろ開発環境更新してもいいかな」と考えられているのではないでしょうか。
しかし、日々の業務に追われ気味のプログラマーがVisual Studio 2022を触って一番最初に面食らうのが、あのConsoleアプリケーションのテンプレートでしょう。
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
「ナニコレ?1行しかないんだけど?Mainどこ行ったの?」
「なんでこれ動くの?」
「レガシーコードと格闘してるうちにC#の仕様ってこんなに大きく変わっちゃったの?」
と、いろんな「?」と不安が頭をグルグル駆け巡ったのではないでしょうか。
ご安心を。実はこの1行、C#9と10の二つの新機能、そして.NET6 SDKを使って実現しているのです。
C#9と10の二つの新機能とは、
のことです。
https://docs.microsoft.com/ja-jp/dotnet/csharp/fundamentals/program-structure/top-level-statements
↑こちらの公式説明で十分ですが、要約すると
たとえば、最初のテンプレートの1行だと、下記になります。
class <Program>$
{
static void $Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
おお、これなら見たことありますね、いつものやつですね。安心ですね。
ごく限定的な条件でのみ自動展開してくれるコンパイラーの機能なので、言語仕様というよりはサクッと書きたい時用のチョイ便利機能みたいな感じですね。
便利であるに越したことはないですけどね。
余談ですが、ステートメントで始まるファイルはビルドアクションを「C#コンパイル」にしないと展開してくれません。(当たり前ですが)
また、ビルドアクションが「C#コンパイル」になっていれば、拡張子はtxtでもhtmlでもなんでも良いです。(誰得な知識ですが)
「Mainの自動展開はわかったけど、usingはどこ行ったん?」
「using無いとSystem.Console.WriteLine()て書かなきゃいかんでしょ」
という疑問を持った方、優秀です。
これはC#10の新機能 global using ディレクティブを使っています。
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/using-directive
↑詳しい説明は公式を読んでください。
要はプロジェクト全体に適用されるusingを定義できますよ、という機能です。
ここで、
global using system;
なんてどこにも定義されていないのに、適用されているのはなぜだ?
と思ったあなた、さらに優秀です。
実はこれは.NET6 SDKの機能で「暗黙のusingディレクティブ」というやつでして、
プロジェクトを作成したときに、プロジェクトディレクトリ内に
obj\Debug\net6.0{プロジェクト名}.GlobalUsings.g.cs
というファイルが自動生成され、下記が記述されています。
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;
なので、わざわざ書かなくてもよかったんですね。
ちなみにこの暗黙のusingディレクティブはプロジェクトテンプレートによっても変わりますし、プログラマーが制御することもできますが、それは次回としましょう。
以上です。
さ、レガシーコードと戦ってこよ。