4 ポイント 投稿者 GN⁺ 2025-05-30 | 4件のコメント | WhatsAppで共有
  • .NET 10 Preview 4 から、単一の C# ファイルを dotnet run app.cs でそのまま実行できる機能が追加され、プロジェクトファイルなしでも C# コードを実行可能になった
  • ファイルベースのアプリ(file-based apps) により、Python や JavaScript のような簡単なスクリプト実行、テスト、アイデア実験がより手軽になった
  • NuGet パッケージ参照、SDK 指定、ビルドプロパティ設定 などもファイル内の ディレクティブ で管理でき、開発の柔軟性が向上
  • shebang 対応により、Unix 系で CLI ユーティリティや自動化スクリプトにも活用可能
  • 必要に応じて プロジェクトベースのアプリ にスムーズに変換でき、学習やプロトタイプから本格的なアプリ開発まで自然につなげられる

dotnet run app.cs とは何か

  • 従来は dotnet CLI で C# コードを実行するには、必ず プロジェクト(.csproj) 構成が必要だった
  • 今では単一の .cs ファイル だけでそのまま実行できるため、参入障壁が大きく下がった
  • スクリプト言語的な用途、自動化、実験、学習などさまざまな用途に適している
  • CLI 統合 により、追加ツールのインストールなしで dotnet さえあればすぐ使える
  • コードが大きくなっても、同じ言語とツールでプロジェクトベースのアプリへ拡張できる

ファイルレベルのディレクティブ対応

  • ファイルベースのアプリでも、プロジェクトの主要設定を .cs ファイル内のディレクティブ として直接宣言できる
  • NuGet パッケージ参照

    • #:package ディレクティブで NuGet パッケージ をそのまま参照できる
      • 例:
        #:package Humanizer@2.14.1  
        
        using Humanizer;  
        
        var dotNet9Released = DateTimeOffset.Parse("2024-12-03");  
        var since = DateTimeOffset.Now - dotNet9Released;  
        
        Console.WriteLine($"It has been {since.Humanize()} since .NET 9 was released.");  
        
  • SDK 指定

    • #:sdk ディレクティブで SDK の種類を指定 できる
      • 例:
        #:sdk Microsoft.NET.Sdk.Web  
        
      • ASP.NET Core の機能(Minimal API、MVC など)も有効化できる
  • MSBuild プロパティ設定

    • #:property でビルドプロパティを直接指定できる
      • 例:
        #:property LangVersion preview  
        
  • シェルスクリプト向け shebang 対応

    • ファイルの先頭に #!/usr/bin/dotnet run を入れることで、Unix 系で実行ファイル としてそのまま利用できる
      • 例:
        #!/usr/bin/dotnet run  
        Console.WriteLine("Hello from a C# script!");  
        
      • 実行権限を付与したあと、そのまま実行:
        chmod +x app.cs  
        ./app.cs  
        

プロジェクトベースのアプリへの変換

  • アプリが大きくなったり、より多くの機能が必要になったときは、dotnet project convert app.cs コマンドで プロジェクトへ簡単に変換 できる
  • ディレクティブは .csproj ファイルのプロパティや参照などへ自動変換される
  • 変換例

    • 次のようなファイル:
      #:sdk Microsoft.NET.Sdk.Web  
      #:package Microsoft.AspNetCore.OpenApi@10.*-*  
      
      var builder = WebApplication.CreateBuilder();  
      builder.Services.AddOpenApi();  
      var app = builder.Build();  
      app.MapGet("/", () => "Hello, world!");  
      app.Run();  
      
    • 変換結果:
    <Project Sdk="Microsoft.NET.Sdk.Web">  
      <PropertyGroup>  
        <TargetFramework>net10.0</TargetFramework>  
        <ImplicitUsings>enable</ImplicitUsings>  
        <Nullable>enable</Nullable>  
      </PropertyGroup>  
      <ItemGroup>  
        <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.*-*" />  
      </ItemGroup>  
    </Project>  
    

従来の C# スクリプト方式との違い

  • これまでもコミュニティツール(CS-Scriptdotnet-scriptCake など)で C# スクリプトの実行は可能だったが、別途ツールのインストールや設定が必要だった
  • 今では 追加インストールや専用モードなしで同じ C# コンパイラと言語 を使い、障壁なくすぐコードを実行できる

始め方

  • .NET 10 Preview 4 をインストール
  • Visual Studio Code を使う場合は、C# Dev Kit最新プレビュー版の C# 拡張機能(2.79.8 以上) のインストールが必要
  • .cs ファイルを作成してすぐにコードを書く
  • ターミナルで dotnet run hello.cs を実行
  • 必要に応じて dotnet project convert hello.cs でプロジェクトへ変換

さらに詳しく

今後の計画

  • VS Code 内でのファイルベースアプリ対応ディレクティブ向け IntelliSense の改善、パフォーマンス向上、デバッグ対応の強化を予定
  • 複数ファイル対応 や実行速度の改善など、追加機能も開発中
  • dotnet run app.cs は C# をより手軽に使えるようにしつつ、.NET の強力さをそのまま提供する
  • プロトタイピング、教育、プロダクション開発まで、より素早く移行できる基盤を提供する

4件のコメント

 
rkttu 2025-08-18

最新バージョンの C# 拡張機能では、File-based App ベースの自動補完体験を提供する DX が用意されていますが、もともと Microsoft は VS Code Marketplace 以外の場所に拡張機能を公開していませんでした。

こうした不便さを解消するために、C# Dev Kit ではない C# Extension 部分(MIT ライセンス部分)だけを別途 autobuild/auto-publish するようにして OpenVSX に登録し、これをもとにした Kiro ベースの簡単なデモ動画を共有します。

https://www.youtube.com/watch?v=pIi7CWOPQSA

 
ndrgrd 2025-05-31

以前 C# Interactive 機能を使ったときは、ローカルにインストールされていないパッケージは使えませんでしたが、今は改善されたようですね。

 
GN⁺ 2025-05-30
Hacker News のコメント
  • この機能は .NET 開発者の生産性に大きな影響を与えそうで、なぜ今まで出てこなかったのか気になるし、.NET プロジェクトで本当に欲しい機能が 1 つある。プロジェクトごとに簡単にカスタムコマンドを定義できる機能で、たとえば npm run <command> のような仕組みがあるといい
  • これを shebang と組み合わせて積極的に活用するよう宣伝しているのが興味深い。こういうアプローチはかなり魅力的に感じる。Go もモジュール導入前からこうしたスクリプト用途に向いていたし、Ubuntu でもこういう使い方をしていた記憶がある。ただ、Go の作者たちは Go をこうしたスクリプト言語として使うことには否定的だった
    • Go の作者たちが反対していたわけではなく、Go をまずプログラミング言語として使うことを勧めていた、という説明。gorun (https://github.com/erning/gorun) のようなツールで以前から簡単に Go をスクリプトのように使えたし、最近では go run github.com/kardianos/json/cmd/jsondiff@v1.0.1 のようにタグを直接指定して一発で実行できるようになっていて、かなり良い機能だ
    • 「shebang」という言葉がいつ頃どこから使われ始めたのか気になる。大学時代や 90~2000 年代初頭の南部地域では普通 hashbang と呼んでいた。shebang という言葉は C# が流行してから初めて聞いたが、実際にはそれ以前からあった用語らしい。ただ、自分の周囲では聞いたことがなかった
    • 以前 .NET の会社で働いていたとき、突然 bash で自動化スクリプトを書く人がいた。そうしたスクリプトを長期的に保守するための専門性はなかったし、最初から品質もあまり良くなかった。なぜ単にツール自体を C# で作らなかったのか理解できなかったが、今回の機能で C# の方がずっと現実的な選択肢に感じられるようになるかもしれない
    • Rust の cargo でもこういうことはできるが、まだ正式サポートではない https://rust-lang.github.io/rfcs/3424-cargo-script.html
  • 機能自体は素晴らしいが、コンパイル済みでも起動オーバーヘッドが約 0.5 秒あるのが欠点で、多くのアプリケーションには向かない。それでも bash に依存するシェルスクリプトの限界もあるし、perl の時代はすでに過ぎ、Ruby がこうした用途には今でも最適なので使い続けてきた。最近はいくつかのスクリプトを Swift に移したが、基本的にインタプリタ方式なのでずっと速く、コンパイル済みの実行ファイルは即座に起動するので非常に印象的だった。Swift CLI アプリ向けのキャッシュコンパイラも自作したことがある(https://github.com/jrz/tools)。なお、dotnet run はすでにコンパイル結果をキャッシュしてくれるので別のキャッシュレイヤーは不要で、無効化するには --no-build、バイナリの場所を確認するには --artifacts-path を使う
    • 0.5 秒という数字はどこから来たのか気になる。私は hello world で試したら 63ms だった。neuecc の CLI ライブラリのベンチマーク(https://neuecc.medium.com/consoleappframework-v5-zero-overhead-native-aot-compatible-cli-framework-for-c-8f496df8d9d1)を見ても、どれも 0.5 秒には達していない。あと Swift が基本的にインタプリタ方式だと触れていたが、.NET JIT は Tiered JIT なのでコードが即座に生成されるわけではなく、複数段階で進む構造になっている
    • dotnet にも 10 か 11 のバージョンで完全なインタプリタモードが導入される予定だと聞いた。こうした用途にもそのモードが適用されるのか気になる https://github.com/dotnet/runtime/issues/112748
    • コンパイル済みでも起動に少しラグがあるのなら、なぜ Python がこの分野であれほど人気を得たのか不思議だ
    • この機能はまだ初期プレビュー段階で、複数の発表でも起動速度の問題は認識しており改善中だと説明されていた
    • 高速な起動が欲しいなら、https://learn.microsoft.com/en-us/dotnet/core/deploying/ の案内どおり簡単にネイティブコードへ変換できる
  • CSX/VBX プロジェクトへの言及が少ないのが残念 https://ttu.github.io/dotnet-script/。しかも C# ランタイムでの F# スクリプトの依存関係処理とも互換性のない形で決めたようで不思議だ https://learn.microsoft.com/en-us/dotnet/fsharp/tools/fsharp-interactive/
    • CSX/VBX などの取り組みが反映されていないという話に対して、実際には公式に複数の方式やツールが言及されていることを案内している https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-app/#existing-ways-to-run-c#-without-projects
    • F# と非互換というのがどういう意味か質問している。構文の違いの話なら、構文を意図的に変えた目的があり、C# スクリプト方言を新設したくなかったので、ファイル import のような機能をあえて入れなかった。これは C# の性質によるものだ
  • Kotlin にも似た機能があり、https://github.com/Kotlin/kotlin-script-examples/blob/master/jvm/main-kts/MainKts.md(こちらではファイル拡張子が必ず *.main.kts でないと動かない)。こういう方式は小さなスクリプトやプロトタイピングにとても良く、JVM の機能を活用するうえでも実用的だ。それでも小さなスクリプトには Ruby が今でもいちばん使いやすく、特に外部プログラムを実行するときのバッククォート構文が本当に便利だ
  • shebang を使って C# スクリプトを bash スクリプトのように実行できる https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-app/#using-shebang-lines-for-shell-scripts
    • .NET 10 preview 4 SDK イメージでファイルの直接実行を試すため shebang をテストしたが、最初はうまくいかなかった。dotnet run <file> では動き、更新後は正常に動作した。原因はファイルが LF ではなく CRLF の改行を使っていたことだった
    • 型安全なスクリプトを書けるようになったのは本当にうれしい。ちなみに macOS では shebang に #!/usr/local/share/dotnet/dotnet run あるいは #!/usr/bin/env -S dotnet run を書く必要がある
  • PowerShell を置き換えられるツールに見える。PowerShell はほとんど ChatGPT 専用言語のように使われがちな傾向もある。多くの会社では PowerShell で書かれたスクリプトがインフラの中核を担っているが、実質的に「読むだけ」の状態に陥ることが多い
    • PowerShell だけでなく、もっと広い範囲まで置き換えられる可能性を感じる。.NET チームなら Python や shell スクリプトに手を出さなくても、先頭に shebang を追加して C# スニペットを貼り付けるだけで、ほぼあらゆるスクリプト処理ができるようになるかもしれない。テスト用サービスもわざわざ express.js で書かずに ASP.NET minimal API でさっと作れば済む
    • Windows システム管理者たちは、おそらく最も大規模に ChatGPT スクリプトを使っている集団ではないだろうか。自分も昔管理者だったなら、MS の公式ドキュメントの水準を考えると間違いなく使っていたと思う
    • C# コードを PowerShell から呼び出すことも可能だ https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/add-type?view=powershell-7.5
    • PowerShell ですべてのインフラをスクリプト化するのは実際には簡単ではなく、そうすると大混乱になるだけだ。実際、関数がいくつかを超えたあたりで C# の方がはるかに効率的で、参入障壁もほとんどない。PowerShell は小規模な ad-hoc スクリプトには最適で、昔の VBScript のような「Windows 標準のスクリプト言語」の位置を占めている
    • PowerShell は .NET コードを直接実行できるので、むしろ PowerShell の体験が拡張される面もある
  • NetPad の機能を事実上置き換えるように見えるし、デバッグまで追加されたら LINQPad も現役の座を追われるかもしれないという予感がある。私も昔は LINQPad にかなり助けられたが、今となってはテキストエディタとしての体験があまりにも不便で、本格的なコードの作成や編集に使うには限界が大きい
    • 自分にとって LINQPad の主な用途は DB とのやり取りや .dump() で値を調べることだ。今回の dotnet run はむしろそれを補完するツールとして使えそうだ。以前、PowerShell を極端に嫌う現場で LINQPad でほぼすべてのスクリプト処理をしていたことがあり、そういう環境では役に立った
    • LINQPad は .NET ではユニークな製品だが、テキストエディタ自体は歴代でも最悪に近いことが多い。neovim や monaco のようなエディタに置き換わってくれるといい。テーブルの可視化や軽快さは素晴らしいが、最近の Jupyter Notebook などの「ノートブック」技術と比べると活用範囲は狭い。単独開発者であることもその限界の一因だろう。それでも毎日の実務で SQL データを触るとき、LINQPad は今でも最高だ
    • LINQPad がすぐに置き換えられることはなさそうだ。競争力の半分は UI にあると思う。VSCode や Visual Studio での dotnet run の使用感が LINQPad とどれくらい似るのか気になる。LINQPad の強みは結果の可視化機能だ。dotnet run がテキストしか出せないか、多くの追加プラグインを必要とするなら LINQPad の需要は続くだろう。構文確認だけが目的なら dotnet run の方が良い選択かもしれない。私もたまにあやふやな構文を LINQPad で試している
    • GUI 機能や拡張ポイントまで含めて実装しない限り、LINQPad をすぐ置き換えるのは難しそうだ
  • この機能には本当に期待している。CI/CD パイプラインで使っている PowerShell スクリプトの一部を置き換えられそうだ。PowerShell も Bash も好きだが、頭の中で C 系構文の言語として解く方がずっと効率的な作業が確かにあり、この機能がその空白を埋めてくれそうだ
  • 実際の提案書(https://github.com/dotnet/sdk/blob/main/documentation/general/dotnet-run-file.md)にはさらに多くの情報があり、特に複数ファイルの処理や実装の詳細(暗黙のプロジェクトファイルなど)について詳しく説明している
 
rkttu 2025-05-30

この機能に関連する実際のサンプルを2つ作ってみたので、返信で共有します。MCPサーバーとAvaloniaを使ったWindows、macOS向けGUIアプリのサンプルコードです。😊

https://forum.dotnetdev.kr/t/…