csharp-scripts
プロジェクトを作成せずにC#/.NETコードを実行したい場合に、.NET CLIを使ってファイルベースのC#アプリを実行するスキル。C#の言語・API実験、単一ファイルのC#アプリ、`#:include`/`#:exclude`で構成された小規模なマルチファイルC#アプリ、または`#:ref`でリンクされたファイルベースC#アプリに適している。言語に依存しない使い捨てスクリプト、汎用的な計算処理、Python/PowerShellスタイルの自動化、フルプロジェクト、既存アプリとの統合には使用しない。
description の原文を見る
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C# language/API experiments, one-file C# apps, small multi-file C# apps composed with `#:include`/`#:exclude`, or C# file-based apps linked with `#:ref`. Do not use for language-agnostic throwaway scripts, generic computations, Python/PowerShell-style automation, full projects, or existing app integration.
SKILL.md 本文
ファイルベースの C# アプリ
使用場面
- ファイルベースのアプリを使って C# の概念、API、または言語機能をテストする
- より大きなプロジェクトに統合する前にロジックをプロトタイプ化する
- 1つのエントリーポイントファイルと数個のヘルパー
.csファイルから小さなユーティリティを構築する
使用しない場面
- ユーザーが言語に依存しないクイックスクリプト、使い捨ての計算、または shell/Python/PowerShell スタイルの自動化を求めている
- ユーザーが完全なプロジェクト、ソリューション統合、または既存アプリでのプロジェクト参照を必要としている
- ユーザーが既存の .NET ソリューション内で作業しており、そこにコードを追加したい
- アプリが十分に大きく、プロジェクト構造、ビルドカスタマイズ、テスト、またはパブリッシュ設定が
.csprojに含まれるべき
入力
| 入力 | 必須 | 説明 |
|---|---|---|
| C# コードまたは意図 | はい | 実行するコード、またはファイルベースのアプリが何をするべきかの説明 |
ワークフロー
ステップ 1: .NET SDK のバージョンを確認
dotnet --version を実行して SDK がインストールされていることを確認し、機能バンドを含む完全なバージョンを記録します。ファイルベースのアプリには .NET 10 以降が必要です。#:include、#:exclude、および推移的なディレクティブの処理には SDK 10.0.300 以降が必要です。SDK 10.0.100/10.0.200 ビルドは単一ファイルアプリを実行できますが、これらのマルチファイルディレクティブはサポートしていません。バージョンが 10 未満の場合は、代わりに古い SDK 用のフォールバックに従います。
ステップ 2: アプリファイルを作成
トップレベルステートメントを使用してエントリーポイント .cs ファイルを作成します。.csproj ファイルとの競合を避けるため、既存のプロジェクトディレクトリの外に配置します。
#!/usr/bin/env dotnet
// hello.cs
Console.WriteLine("Hello from a file-based app!");
var numbers = new[] { 1, 2, 3, 4, 5 };
Console.WriteLine($"Sum: {numbers.Sum()}");
ガイドライン:
- トップレベルステートメントを使用します(
Mainメソッド、クラス、または名前空間の定型句は不要) usingディレクティブをファイルの上部に配置します(#!行の後、および#:ディレクティブがある場合はその後)- 型宣言(クラス、レコード、列挙型)をすべてのトップレベルステートメントの後に配置します
ステップ 3: アプリを実行
dotnet hello.cs
自動的にビルドして実行します。キャッシュされるため、後続の実行は高速です。-- の後に引数を渡します:
dotnet hello.cs -- arg1 arg2 "multi word arg"
ステップ 4: ディレクティブを追加(必要な場合)
ディレクティブはファイルの最上部(オプションのシェバング行の直後)に配置し、using ディレクティブや他の C# コードの前に置きます。すべてのディレクティブは #: で始まります。
#:package — NuGet パッケージ参照
バージョンを指定します。アプリが意図的に集中パッケージ管理を使用する場合を除きます。最新の利用可能なパッケージで問題ない場合は @* を使用します(プレリリースは @*-*):
#:package Humanizer@2.14.1
using Humanizer;
Console.WriteLine("hello world".Titleize());
#:property — MSBuild プロパティ
任意の MSBuild プロパティをインラインで設定します。構文: #:property PropertyName=Value
#:property AllowUnsafeBlocks=true
#:property PublishAot=false
#:property NoWarn=CS0162
MSBuild 式およびプロパティ関数がサポートされます:
#:property LogLevel=$([MSBuild]::ValueOrDefault('$(LOG_LEVEL)', 'Information'))
一般的なプロパティ:
| プロパティ | 目的 |
|---|---|
AllowUnsafeBlocks=true | unsafe コードを有効にする |
PublishAot=false | ネイティブ AOT を無効にする(デフォルトで有効) |
NoWarn=CS0162;CS0219 | 特定の警告を抑制する |
LangVersion=preview | プレビュー言語機能を有効にする |
InvariantGlobalization=false | カルチャ固有のグローバリゼーションを有効にする |
#:project — プロジェクト参照
相対パスで別のプロジェクトを参照します:
#:project ../MyLibrary/MyLibrary.csproj
#:ref — ファイルベースアプリ参照
別のファイルベースアプリプロジェクトとして別の .cs ファイルを参照する場合、同じコンパイルに含める代わりに別のアセンブリにコンパイルする場合に使用します。通常のヘルパーファイルでエントリーポイントと同じアセンブリを共有する場合は #:include を使用します。プロジェクト参照のような境界が必要な場合は #:ref を使用します。
#:property ExperimentalFileBasedProgramEnableRefDirective=true
#:ref ../Shared/Formatter.cs
Console.WriteLine(Formatter.Title("hello world"));
ガイドライン:
- 参照されたファイルは独自の仮想プロジェクトとしてコンパイルされ、プロジェクト参照として追加されます。
- 参照されたファイルがトップレベルステートメントなしのライブラリの場合は、
#:property OutputType=Libraryをその参照ファイルに配置します。 - 参照元アプリで使用する必要があるメンバーは public である必要があります。internal メンバーはアセンブリ境界を越えて見えません。
#:refは推移的です。参照ファイルは独自の#:refおよび他の#:ディレクティブを含むことができます。- 相対パスはディレクティブを含むファイルの相対で解決されます。
- 一部の SDK ビルドは
#:property ExperimentalFileBasedProgramEnableRefDirective=trueが必要です。SDK が#:refをそれなしで受け入れる場合はそのプロパティを削除します。
#:sdk — SDK 選択
デフォルト SDK (Microsoft.NET.Sdk) をオーバーライドします:
#:sdk Microsoft.NET.Sdk.Web
#:include および #:exclude — マルチファイルアプリ
.NET SDK 10.0.300 以降では、ファイルベースのアプリは同じ仮想プロジェクトに追加ファイルを含むことができます。これらのディレクティブを使用する前に、dotnet --version の完全な出力を確認してください。10.0.100 または 10.0.200 SDK は依然として .NET 10 ですがそれらをサポートしていません。ヘルパーソースファイルとサポート対象アセット用に #:include を使用し、include パターンまたはデフォルト項目セットからファイルを削除するために #:exclude を使用します。
#!/usr/bin/env dotnet
#:include Helpers.cs
#:include Models/*.cs
#:exclude Models/Generated/*.cs
Console.WriteLine(Formatter.Title("hello world"));
ガイドライン:
dotnetに渡されるファイルをエントリーポイントとして扱います。トップレベルステートメントをそこに配置します。- クラス、レコード、列挙型などの宣言を included
.csファイルに配置します。 - 広い再帰的グロブよりも
Helpers.csまたはModels/*.csなどの明示的なグロブを優先します。 - パスはディレクティブを含むファイルの相対で解決されます。
- 非エントリーポイント C# ファイルからのインクルードディレクティブも処理されるため、ヘルパーファイルは独自の
#:package、#:property、#:sdk、#:project、#:ref、#:include、または#:excludeディレクティブを宣言できます。 - included ファイル全体で重複ディレクティブを避けます。ディレクティブ種別が明示的に重複をサポートしていない限り。重複した
#:package、#:property、#:sdk、#:include、および#:excludeエントリーは失敗する可能性があります。 - アプリが
#:includeを使用する場合、Unix ライクシステム上のエントリーポイントファイルにシェバング (#!/usr/bin/env dotnet) を追加して、エントリーポイントをツールに明確にします。シェバングファイルはLF行終了を使用し、BOM を付けません。
例のレイアウト:
scratch/
hello.cs
Helpers.cs
Models/
Person.cs
#!/usr/bin/env dotnet
// hello.cs
#:include Helpers.cs
#:include Models/*.cs
var person = new Person("Ada");
Console.WriteLine(Formatter.Title(person.Name));
// Helpers.cs
static class Formatter
{
public static string Title(string value) => value.ToUpperInvariant();
}
// Models/Person.cs
record Person(string Name);
ステップ 5: クリーンアップ
ユーザーが完了したらアプリファイルを削除します。キャッシュされたビルド成果物をクリアするには:
dotnet clean hello.cs
Unix シェバング サポート
Unix プラットフォームで .cs ファイルを直接実行可能にします:
-
ファイルの最初の行にシェバングを追加します:
#!/usr/bin/env dotnet Console.WriteLine("I'm executable!"); -
実行権限を設定します:
chmod +x hello.cs -
直接実行します:
./hello.cs
シェバングを追加するときは LF 行終了を使用します(CRLF ではなく)。このディレクティブは Windows で無視されます。
ソースジェネレーション JSON
ファイルベースのアプリはデフォルトでネイティブ AOT を有効にします。JsonSerializer.Serialize<T>(value) のようなリフレクションベースの API は AOT 下での実行時に失敗します。代わりにソースジェネレーション シリアライゼーションを使用します:
using System.Text.Json;
using System.Text.Json.Serialization;
var person = new Person("Alice", 30);
var json = JsonSerializer.Serialize(person, AppJsonContext.Default.Person);
Console.WriteLine(json);
var deserialized = JsonSerializer.Deserialize(json, AppJsonContext.Default.Person);
Console.WriteLine($"Name: {deserialized!.Name}, Age: {deserialized.Age}");
record Person(string Name, int Age);
[JsonSerializable(typeof(Person))]
partial class AppJsonContext : JsonSerializerContext;
プロジェクトへの変換
ファイルベースのアプリがこのワークフローを超えて成長する場合、完全なプロジェクトに変換します:
dotnet project convert hello.cs
.NET 9 以前用のフォールバック
.NET SDK バージョンが 10 未満の場合、ファイルベースのアプリは利用できません。代わりに一時的なコンソールプロジェクトを使用します:
mkdir -p /tmp/csharp-file-based-app && cd /tmp/csharp-file-based-app
dotnet new console -o . --force
生成された Program.cs をアプリコンテンツに置き換え、dotnet run で実行します。dotnet add package <name> で NuGet パッケージを追加します。完了したらディレクトリを削除します。
検証
-
dotnet --versionが 10.0 以降を報告する(またはフォールバック パスが使用される) - アプリが
#:include、#:exclude、または included ファイルからの推移的ディレクティブを使用する場合、dotnet --versionが SDK 10.0.300 以降を報告する - アプリはエラーなしでコンパイルされる(
dotnet build <file>.csで明示的にチェック可能) -
dotnet <file>.csが期待される出力を生成する - マルチファイルアプリは必要なすべてのヘルパーファイルを含み、意図しないマッチを除外する
- アプリファイルとキャッシュされた成果物はセッション後にクリーンアップされる
一般的な落とし穴
| 落とし穴 | 解決策 |
|---|---|
.cs ファイルが .csproj を含むディレクトリ内にある | アプリをプロジェクトディレクトリの外に移動するか、dotnet run --file file.cs を使用します |
バージョンなしの #:package | バージョンを指定します: #:package PackageName@1.2.3 または最新は @* |
間違った構文の #:property | = の周りに空白やクォートなしで PropertyName=Value を使用します: #:property AllowUnsafeBlocks=true |
| C# コードの後に配置されたディレクティブ | すべての #: ディレクティブはオプションのシェバング行(存在する場合)の直後、using ディレクティブや他の C# ステートメントの前に表示する必要があります |
| ヘルパーファイルがコンパイルされていない | #:include Helper.cs または適切なグロブをエントリーポイントファイルに追加します |
| 共有ファイルにアセンブリ境界が必要 | #:include Shared.cs の代わりに #:ref Shared.cs を使用し、参照ファイルにエントリーポイントがない場合は #:property OutputType=Library を設定します |
| 広い include が無関連ファイルを取り込む | 狭い include パターンを優先し、生成された、バックアップ、または実験的なファイル用に #:exclude を使用します |
| included ファイル内の重複ディレクティブ | package、property、SDK、include、および exclude ディレクティブをエントリーポイントと included C# ファイル全体で一意に保ちます |
| リフレクションベースの JSON シリアライゼーション失敗 | JsonSerializerContext を使用したソースジェネレーション JSON を使用します(ソースジェネレーション JSON を参照) |
| 予期しないビルド動作またはバージョンエラー | ファイルベースのアプリは global.json、Directory.Build.props、Directory.Build.targets、および nuget.config を親ディレクトリから継承します。継承された設定が競合する場合は、アプリを分離ディレクトリに移動します |
詳細情報
ファイルベースのアプリの完全なリファレンスについては、https://learn.microsoft.com/en-us/dotnet/core/sdk/file-based-apps を参照してください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- dotnet
- リポジトリ
- dotnet/skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/dotnet/skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。