【実験】C#13.0以前でdotnet run file.csを動かす
C#の新記法だけど…
dotnet CLIの新コマンド、dotnet run file.cs
ではプロジェクトファイル(*.csproj
)いらずで実行できるようにするため、「ignored directive」という記法がC#に追加されています。
#!/usr/bin/env -S dotnet run
#:sdk Microsoft.NET.Sdk.Web
#:property TargetFramework net10.0
#:property LangVersion preview
#:package System.CommandLine 2.0.0-*
既にpreviewに実装済み[1]なので、C#14.0の内容ってことになるっぽいですが、C#の文法的には意味のないもの(無視されるもの)です。
なので、実はC#13.0以前のバージョンでも使えます。
ただし、ignored directive、dotnet run file.csは .NET SDKのサポートがいる ので、.NET SDK 10-preview 4以降が必要です。
古いバージョンのC#でdotnet run file.csする方法
- SDKは.NET 10 SDK以降にする
- エントリーポイントのコードをトップレベルステートメントで記述する
-
#:property
でLangVersion
を対応可能なバージョンの範囲で下げる -
#:property
でTargetFramework
を有効なバージョンを指定する
SDKは.NET 10 SDK以降にする
C#は言語バージョンとランタイム(.NET Runtime)のバージョンには対応はあるものの、必ず合わせないといけないというわけではありません。
たとえば、
- 最新のランタイム.NET 9で古いC#8.0を使う
- 古い.NET Framework 4.8で最新のC#13.0を使う
とかが(一部制限はあるものの)できます。
ignored directive、dotnet run file.csは .NET SDK 10 からなのでこれにします。ただし、言語バージョンは14から落とします。
エントリーポイントのコードをトップレベルステートメントで記述する
dotnet run file.csで指定できるC#コードはトップレベルステートメントで記述されたコードです。
トップレベルステートメントはC#9.0で導入されたので、
つまり、C#9.0以降なら使えるということになります。
C#9.0は2020年公開で結構前なので、(C#自体は)少し前の古いC#でもいいということになります。
#:property
でLangVersion
を対応可能なバージョンの範囲で下げる
通常、csprojでLangVersion
を指定すればC#のバージョンを指定できます。dotnet run file.csで動くようにするにはdirectiveにLangVersion
を指定します。
#!/usr/bin/env -S dotnet run
#:property LangVersion 10
Console.WriteLine("Hello, World!");
#:property
でTargetFramework
を有効なバージョンを指定する
C#プログラムが実行される.NETランタイムも、古いバージョンを指定することでそのバージョンで実行できるようです。
#!/usr/bin/env -S dotnet run
#:property LangVersion 9
#:property ImplicitUsings disable
#:property TargetFramework net48
using System;
Console.WriteLine("Hello, World!");
サポートが切れたバージョンのランタイムも指定できますが、Warningがでます。また未インストールのランタイムは指定してビルド自体まではできるものの、実行時に失敗します。
実用性は?
あまりありません!
SDKは最新だけど、言語バージョンはプロジェクトの方針で古いまま維持したい、というケースくらい…?
(まあでもそんなプロジェクトで新しいdotnet run files.csを使うのか???)
あとは、古い環境でどう動くかを簡単に書いたコードでテストしたい、みたいなときにも使えるかもしれません。
dotnet run files.csで指定できるファイルはフォルダ分け不要で同じフォルダに置いてあってもいいので、簡易テストには向いてます。
Discussion