世界を動かす技術を、日本語で。

C#ファイルを直接実行するには「dotnet run app.cs」を使用する

概要

  • .NET 10 Preview 4 でC#のファイル単体実行が可能に
  • プロジェクト作成不要で dotnet run app.cs が利用可能
  • 新しい ファイルレベルディレクティブ で柔軟な記述
  • スクリプトから本格的なプロジェクトへの シームレスな移行
  • CLI・VS Code での利用がより簡単に

.NET 10 Preview 4: C#ファイル単体実行機能の紹介

  • dotnet run app.cs コマンドで、C#ファイルを直接実行可能
  • プロジェクトファイルや.scaffold作成不要、学習やスニペット確認、アイデア検証に最適
  • PythonやJavaScriptのような スクリプト的な使い方 が可能
  • C#入門者やプロトタイピング、オートメーション用途 での利便性向上
  • 従来の .csproj構造不要、CLIのみで実行可能

ファイルベースアプリの新ディレクティブ

  • #:package でNuGetパッケージを直接参照可能
    • 例: #:package Humanizer@2.14.1
  • #:sdk でSDK指定が可能
    • 例: #:sdk Microsoft.NET.Sdk.Web でWeb機能を有効化
  • #:property でMSBuildプロパティを設定可能
    • 例: #:property LangVersion preview
  • シェバン行(#!) でUnix系シェルスクリプトとして実行可能
    • 例: #!/usr/bin/dotnet run

スクリプトからプロジェクトへの移行

  • dotnet project convert app.cs コマンドで、ファイルベースアプリをプロジェクト化
    • .csproj生成、コード移動、ディレクティブのMSBuildプロパティ変換
  • 例:Webアプリ用ディレクティブとパッケージ指定のコードが、正規の.csprojに変換

既存のC#スクリプト実行手法との比較

  • CS-Script, dotnet-script, Cake などの既存ツールも引き続き有用
  • 新機能は C#標準機能として統合、追加インストールや設定不要
  • 同一言語・同一コンパイラ でプロジェクト移行も自然

はじめ方と推奨環境

  • .NET 10 Preview 4 を公式サイトからインストール
  • Visual Studio Code 推奨
    • 最新の C# Dev Kit および C#拡張(2.79.8以上のプレリリース) を導入
  • サンプルファイル作成例
    • Console.WriteLine("Hello, world!");
    • 実行:dotnet run hello.cs
  • プロジェクト変換例
    • dotnet project convert hello.cs

今後の展望と開発ロードマップ

  • VS CodeでのIntelliSense強化 やファイルベースディレクティブのサポート改善
  • 複数ファイル対応や実行速度向上 をCLIで検討中
  • フィードバックは GitHub で募集中、.NET 10以降も継続的に進化予定

まとめ

  • C#開発のハードル低減、アイデアから実装までのスピード向上
  • プロトタイピング、教育、業務利用まで幅広く活用可能
  • 一貫した開発体験 と.NETエコシステムの強みを両立

Hackerたちの意見

これ、すごくいいPowerShellの代替になりそうだね。PowerShellは究極のChatGPT言語だと思う。良い面も悪い面もあるけど、たいていは悪い方かな。大抵の職場では「書き込み専用」のPowerShellスクリプトが動いて、インフラ関連のことを全部やってるし。

これ、すごくいいPowerShellの代替になりそうだね。もっと多くのことを置き換えられそうな気がする。つまり、.NETの職場がPythonやシェルスクリプトを使う理由って、アドホックなスニペットにシェバンを付けるだけで済むなら、わざわざやる必要ないよね?それに、テストサービスのためにexpress.jsを作る必要があるのかな?スクリプトでASP.NETのミニマルAPIを組み立てるだけで済むのに。

低レベルのコーディングが好きならいいけど、高レベルのコマンドレットの方が好きなら別だね。

Powershellが.NETコードを実行できるから、これがPowershellを強化するのか気になるな。

PowerShellスクリプトが全てのグルーやインフラ関連のことをやってる。正直言って、普通はそれができないって報告できるよ。大混乱になるだけだからね。C#は数個のメソッド以上のことには向いてるし、ほとんど障壁がない。PSは小規模なアドホックな作業には最適だけど、数年前のVBScriptみたいに「すべてのWindowsプラットフォームにあるスクリプト」って感じだね。

PSからC#を呼び出すこともできるよ。 https://learn.microsoft.com/en-us/powershell/module/microsof...

これ、めっちゃ楽しみ!CI/CDパイプラインで使ってるPowerShellスクリプトのいくつかを置き換えられそう。PowerShellやBashも好きだけど、C言語っぽい構文の方が効率よく解決できるタスクがあって、これがその隙間を埋めてくれる感じ。

これ、Kotlinでもあるよね:https://github.com/Kotlin/kotlin-script-examples/blob/master... (この場合、ファイル拡張子が重要だから、"*.main.kts"って名前にしないと動かないよ)。小さなスクリプトやプロトタイピングを書くのには素晴らしいけど、Rubyが小さなスクリプトにはやっぱり好きかな。外部プログラムを実行するためのバックティックがすごく使いやすいし。

いいね、でも残念ながら、コンパイルしても起動時のオーバーヘッドが約半秒かかるから、多くのアプリには向いてないね。それでも、シェルスクリプティングは面倒だから、みんなBashの機能に頼っちゃうし、Perlはもう古い感じ。Rubyはこの目的にはずっと使ってたけど、最近はSwiftにいくつかのスクリプトを移行したよ。Swiftはデフォルトでインタープリタだから、コンパイル版は瞬時に始まるし、Swift CLIアプリ用に透明なキャッシングレイヤーも作った。結果:最高の言語の一つで瞬時にネイティブツールができる。Swift Script Caching Compiler (https://github.com/jrz/tools) は、dotnet runには必要ないけど、すでにコンパイル版をキャッシュしてるからね(--no-buildで無効にしたり、--artifacts-pathでバイナリを確認できる)。

これ、毎回再コンパイルするの?入力のハッシュでバイナリをキャッシュするのは簡単なはずだよね?最初の実行がサブ秒で、その後は瞬時に再実行できるなら、許容範囲だと思う。

いいね、でも残念ながら、コンパイルしても起動時のオーバーヘッドが約半秒かかるから、多くのアプリには向いてないよ。それってどのアプリのこと?一例として、基本的なウェブサービスを立ち上げるのを紹介してるけど。

半秒って数字はどこから来たの?ハローワールドをテストしたら、オーバーヘッドは63msだったよ。neueccがCLIライブラリのオーバーヘッドをベンチマークしたけど、どれも半秒には達してないよ:https://neuecc.medium.com/consoleappframework-v5-zero-overhe... > Swiftはデフォルトで解釈するから、これに関してはずっと良い仕事してるよ。 .NETのJITはティアードJITだから、すぐにコードを出力するわけじゃないし。

すぐに起動させたいなら、https://learn.microsoft.com/en-us/dotnet/core/deploying/を使って簡単にネイティブコードに変換できるよ。

Dotnetは10か11で完全に解釈されたモードが追加されるから、こういうのに切り替えるのかな? https://github.com/dotnet/runtime/issues/112748

Pythonは昔のPerlのニッチにぴったりみたいだね。

まだ初期プレビュー段階なんだ。いくつかのプレゼンテーションで起動速度について言及していて、改善に取り組んでいるって言ってたよ。

素晴らしいけど、残念ながらコンパイルしても起動オーバーヘッドが約0.5秒かかるから、多くのアプリには向いてないんだよね。じゃあ、なんでPythonがこの分野でこんなに人気なの?

代わりに “tcc -run” を使ってるよ。瞬時に動くからね。

CSX/VBXの取り組みが認められてないのが残念だな。https://ttu.github.io/dotnet-script/ それに、C#ランタイムの知恵に基づいて、F#がスクリプトで依存関係を参照する方法とは互換性のないアプローチを選んだのもね。https://learn.microsoft.com/en-us/dotnet/fsharp/tools/fsharp...

「互換性がない」ってどういう意味?構文のことを言ってるなら、それは明確さのために意図的に違うんだよ。それに、新しいC#スクリプトの方言を作りたくないから、他のファイルを「インポート」するのは無理なんだ(C#の動き方じゃないし)。

CSX/VBXの取り組みが認められていないのは残念だと思う。彼らはそれと他の取り組みを認めてるよ。 https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...

シェバンを使ってC#スクリプトをBashスクリプトみたいに実行することもできるよ:https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...

.net10プレビュー4 SDKイメージでファイルを直接実行してもシェバンが動かなかったんだ。dotnet runで実行すると動くよ。追記:今は動いてる、ファイルがLFじゃなくてCRLFを使ってたんだ。

それは素晴らしい!やっと型安全なスクリプトが書けるようになるね。macOSでは、シェバンが #!/usr/local/share/dotnet/dotnet run#!/usr/bin/env -S dotnet run になることに注意してね。

シェバンを使うことを積極的に推奨してるのが面白いね。結構魅力的だと思う。Goのモジュール以前はこの方法でうまくいってたし、Ubuntuもこんな感じで使ってたと思うけど、Goの作者たちはスクリプト言語として使うことには反対してたんだよね。

以前、.NETの会社で自動化スクリプトをランダムにbashで書いてたことがあるんだけど、長期的にそれを維持する専門知識(正直言って、最初からちゃんと書く技術も)が全然なかったんだ。なんでC#でツールを作らなかったのか理解できなかったよ。これがもっと実行可能なアプローチに見えるようになるといいな。

作者たちは反対してるわけじゃなくて、まずプログラミング言語として使うことを支持してるんだよ。gorunみたいなツールは、Goが登場してからほぼずっと存在してるから、そういう使い方をしたいなら簡単にできるよ。最近、これをサポートする機能も追加されたんだ:go run github.com/kardianos/json/cmd/jsondiff@v1.0.1 これでタグを引っ張って直接実行できるのも、ちょっとクールだよね。

C#は俺の2番目に好きな言語だ。数年前に、依存関係ゼロでRust(俺の1番好きな言語)用のシェバンを作ったよ。 https://neosmart.net/blog/self-compiling-rust-code/

もう15年以上C#でコーディングしてるけど、新しいアプローチを試すためにプロジェクト構造を作るよりも、これを使う方がいいと思ってる。

JavaがCみたいにvoid main() {}を許可して、今やシェバンC#スクリプトもあるけど、すべてが一つのメタ言語に収束してるのかな?

ネイティブサポートのあるまともなTypeScriptのサブセットがあれば、どこでも使うよ。でも、今のところC#はTypeScriptほど便利じゃないな。もう数年、便利な言語機能やAPIが追加されれば、いい感じになると思う。