mcpField
C
csharp

csharp

github.com/alexander-danilenko開発1886 回インストール2 週間前に更新
リポジトリ

csharp について

C# コードを書く、または変更する開発者向けの C# 12 と .NET 8 以降の規約スキルです。非同期処理、データアクセス、設定、API 境界を扱い、本番で起きやすい問題にも焦点を当てています。

主な機能

  1. 01Nullable 警告をエラー扱い
  2. 02C# 12 の言語規約
  3. 03想定内の失敗に Result パターン
  4. 04非同期処理とキャンセルの指針
  5. 05EF Core クエリの実践
  6. 06検証付きの型付き設定

活用シーン

  1. 01.NET サービスの作成や変更
  2. 02非同期処理とキャンセルの確認
  3. 03EF クエリと API データ公開の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/alexander-danilenko/cortex-claude-code-plugins --skill csharp

インストール後、Claude Code で/csharpを入力して読み込まれたか確認します。

詳細

C# の規約

C# 12 / .NET 8 以降におけるプロジェクト内の規約です。新規作成または変更するコードに適用してください。指示がない限り、変更していないファイルまで書き換えて規約に合わせる必要はありません。

規約

  • <Nullable>enable</Nullable> を設定し、警告をエラーとして扱います。 null 許容注釈の効果があるのは、警告によってビルドが止まる場合だけです。無視すると、どの参照が null になり得るかを偽って示す飾りになってしまいます。

  • C# 12 の標準機能を使います。 ファイルスコープの名前空間、プライマリコンストラクター、コレクション式、required メンバーを使います。DTO と値オブジェクトにはレコードを使います。データを比較するときは値の等価性が必要であり、手書きの Equals/GetHashCode の組み合わせは互いにずれていくためです。

  • 型のテストとキャストを連ねる代わりに、パターンマッチングを使います。 網羅性が保証された階層に対する switch 式なら、未処理のケースがあるとコンパイラーが警告します。if/else if の連鎖では、新しい型が追加されても何も通知されずに処理が抜け落ちます。

  • 想定される失敗には Result パターンを、真に例外的な事態には例外を使います。 「見つからない」や「入力が無効」は通常の結果であり、呼び出し元が対処する必要があるため、戻り値の型に含めます。制御フローに例外を使うと、シグネチャから失敗が見えなくなり、発生のたびにスタックの巻き戻しコストがかかります。閉じたレコード階層を使えば、結果を網羅する switch を記述できます。

    public abstract record Result<T>
    {
        public sealed record Ok(T Value) : Result<T>;
        public sealed record Fail(string Error) : Result<T>;
    }
    
    var message = GetUser(id) switch
    {
        Result<User>.Ok(var user) => $"Found {user.Name}",
        Result<User>.Fail(var error) => error,
    };
    
  • 非同期処理は末端まで一貫して非同期にします。 .Result と .Wait() は、同期コンテキストがあるとデッドロックを引き起こし、それ以外の環境でもスレッドプールのスレッドを消費します。呼び出しチェーンの末端を非同期にする必要があるなら、先頭も非同期にします。

  • すべての非同期パブリックメソッドで CancellationToken を受け取り、引き渡します。 これがないと、キャンセルされたリクエストでもデータベースクエリや HTTP 呼び出しが完了まで実行され続け、すでに離れた呼び出し元に処理コストが発生します。

  • API から EF エンティティを公開しないでください。 Select で DTO に投影します。そうしないと、次にスキーマへ追加されるものまで公開することになり、遅延読み込みによってシリアル化時に N+1 クエリが大量に発生します。

  • テストの失敗ではなく、本番環境のインシデントにつながる EF 固有の注意点: 読み取り専用クエリにはすべて AsNoTracking() を指定します。大規模な結果セットで変更追跡を行うのは、純粋なオーバーヘッドだからです。複数のコレクションを Include する場合は AsSplitQuery() を使います。単一の結合では、直積のように行数が増えるためです。エンティティを読み込んで変更するのではなく、一括変更には .NET 7+ の ExecuteUpdateAsync/ExecuteDeleteAsync を使います。論理削除にはグローバルな HasQueryFilter を使い、どのクエリでもフラグの指定を忘れないようにします。

  • 1 つのインターフェイスに複数の実装がある場合は、キー付きサービスを使います(.NET 8)。 AddKeyedScoped<INotifier, EmailNotifier>("email") で登録し、[FromKeyedServices("email")] で解決します。列挙型で切り替えるファクトリーより優れています。コンテナーが引き続きライフタイムを管理できるためです。

  • 検証済みの型安全な設定には IOptions<T> を使います。 configuration["Some:Key"] は、キーの入力ミスがあった場合、呼び出し箇所で実行時に失敗します。ValidateOnStart を設定したバインド済みオプションクラスなら、起動時にフィールド名とともに失敗します。

  • 呼び出しごとに new HttpClient() を使うのではなく、IHttpClientFactory を使います。 TIME_WAIT 接続が残ることでソケットが枯渇するのは典型的な障害であり、高負荷時にしか発生しません。

  • プロファイラーで割り当てが問題だとわかった箇所では、Span<T>/Memory<T> とプーリングを使います。 コードが複雑になるため、原則としてではなく、測定結果がある箇所でその複雑さを受け入れてください。

コメント