Claude Cursor Skill

writing-csharp

Idiomatic C# /.NET development. Use when writing C# code, changing `.csproj`

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download alexei-led-cc-thingz-src_skills_writing-csharp-ce56bb4.zip · 3 KB
Part of alexei-led/cc-thingz — 91 skills

Install

skills CLI npx skills add https://github.com/alexei-led/cc-thingz/tree/master/src/skills/writing-csharp
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install alexei-led-cc-thingz@llmmart
Git git clone https://github.com/alexei-led/cc-thingz.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole alexei-led/cc-thingz collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

C# /.NET Development

Check the nearest *.csproj, Directory.Build.props, global.json, and CI for TargetFramework(s), LangVersion, nullable context, and analyzer policy before using newer syntax. Without an explicit LangVersion, the C# version follows the TFM (net8.0 defaults to C# 12; net6.0 defaults to C# 10, which lacks primary constructors and collection expressions). Project conventions win over these defaults, and raising LangVersion or the TFM to unlock syntax is a separate decision — ask first, don't do it on your own.

Defaults

  • BCL and existing NuGet packages first. Keep the app's existing choices: controllers vs minimal APIs, DI container, ORM, test framework.
  • Nullable reference types stay on. Model absence with ?; handle a missing result explicitly (e.g. return NotFound/Problem) instead of !. Never suppress a warning; fix it at the source.
  • Async end to end: no .Result, .Wait(), or GetAwaiter().GetResult(). Pass CancellationToken through cancellable boundaries, including EF calls.
  • Never let a singleton capture a scoped service (e.g. a DbContext); use IServiceScopeFactory or IDbContextFactory when a singleton needs scoped data.
  • Validate request DTOs and message payloads at the handler before mapping to domain types; model binding alone is not validation. Return response DTOs from API boundaries, not entities.
  • Bind and validate options at startup (ValidateOnStart); inject typed options instead of reading config ad hoc.
  • Background services honor the stopping token; replace Thread.Sleep with a cancellable wait (Task.Delay with the token, or PeriodicTimer).

CLIs

  • Existing CLI stack first; the BCL is enough for small tools. Add System.CommandLine or Spectre.Console only when the command surface justifies it.
  • Keep Program.cs thin: test the command handler, or a Run(args, stdout, stderr) seam, and assert exit code and output with dotnet test --filter, including a non-zero exit and a stderr message on bad input.

References

  • testing.md: read when adding or reshaping tests, or when dotnet test is slow.
  • linting.md: read when changing dotnet format, analyzers, or warning policy.

Done when the relevant build/test/lint checks pass on what you changed, or you name each check that did not run and why.

Files (cc-thingz)
  • .agentbundler
    • targets
      • claude.json 234 B
        {
          "frontmatterPatch": {
            "agent": "engineer",
            "allowed-tools": [
              "Read",
              "Bash",
              "Grep",
              "Glob",
              "Edit",
              "Write",
              "LS"
            ],
            "context": "fork",
            "user-invocable": false
          }
        }
        
  • references
    • linting.md 749 B
      # C# /.NET Linting
      
      Use the project's command first. Edit loop, scoped to the nearest project or solution:
      
      ```bash
      dotnet format path/to/App.csproj --include src/Orders/OrderService.cs
      dotnet format path/to/App.csproj --verify-no-changes
      dotnet build path/to/App.csproj
      ```
      
      - Run `dotnet build` when formatting alone cannot prove the change, and after edits to `.csproj`, `.props`, or `.targets`.
      - Run the broader solution build before finishing when the change touches shared props, targets, package references, or public contracts.
      - Keep nullable, analyzer, and `TreatWarningsAsErrors` policy intact unless the task changes that policy. Fix warnings at the source with null checks or pattern matching, not `#pragma` or suppression attributes.
      
    • testing.md 996 B
      # C# /.NET Testing
      
      Use the project's framework (xUnit, NUnit, or MSTest); do not switch in scoped work.
      
      ```bash
      dotnet test path/to/Tests.csproj --filter "FullyQualifiedName~OrderServiceTests"
      dotnet test path/to/Tests.csproj
      dotnet test path/to/App.sln
      ```
      
      - Edit loop: the nearest test project with a `--filter`. Run the solution when the change crosses projects.
      - Parameterize case matrices with the framework's style (`[Theory]`, `[TestCase]`, `[DataRow]`).
      - Async tests return `async Task`, never `async void`.
      - ASP.NET Core HTTP behavior: the project's existing integration harness (usually `WebApplicationFactory`) before a new one.
      - EF-backed code: a disposable test database or the project's existing seam, not mocked `IQueryable` chains.
      - Replace real sleeps with a controllable clock (.NET 8+: `TimeProvider`, faked with `FakeTimeProvider` from `Microsoft.Extensions.TimeProvider.Testing` when the project accepts that package), cancellation, or deterministic synchronization.
      
  • SKILL.md 2.7 KB
    ---
    description: Idiomatic C# /.NET development. Use when writing C# code, changing `.csproj`
      or `.sln`, or working on ASP.NET Core apps, libraries, CLIs, workers, and xUnit/NUnit/MSTest
      suites. Emphasizes nullable references, async/await, boundary validation, focused
      `dotnet` feedback, and minimal dependencies. NOT for Go, Python, TypeScript,
      shell scripts, or infra-only work.
    name: writing-csharp
    ---
    
    # C# /.NET Development
    
    Check the nearest `*.csproj`, `Directory.Build.props`, `global.json`, and CI for `TargetFramework(s)`, `LangVersion`, nullable context, and analyzer policy before using newer syntax. Without an explicit `LangVersion`, the C# version follows the TFM (`net8.0` defaults to C# 12; `net6.0` defaults to C# 10, which lacks primary constructors and collection expressions). Project conventions win over these defaults, and raising `LangVersion` or the TFM to unlock syntax is a separate decision — ask first, don't do it on your own.
    
    ## Defaults
    
    - BCL and existing NuGet packages first. Keep the app's existing choices: controllers vs minimal APIs, DI container, ORM, test framework.
    - Nullable reference types stay on. Model absence with `?`; handle a missing result explicitly (e.g. return `NotFound`/`Problem`) instead of `!`. Never suppress a warning; fix it at the source.
    - Async end to end: no `.Result`, `.Wait()`, or `GetAwaiter().GetResult()`. Pass `CancellationToken` through cancellable boundaries, including EF calls.
    - Never let a singleton capture a scoped service (e.g. a `DbContext`); use `IServiceScopeFactory` or `IDbContextFactory` when a singleton needs scoped data.
    - Validate request DTOs and message payloads at the handler before mapping to domain types; model binding alone is not validation. Return response DTOs from API boundaries, not entities.
    - Bind and validate options at startup (`ValidateOnStart`); inject typed options instead of reading config ad hoc.
    - Background services honor the stopping token; replace `Thread.Sleep` with a cancellable wait (`Task.Delay` with the token, or `PeriodicTimer`).
    
    ## CLIs
    
    - Existing CLI stack first; the BCL is enough for small tools. Add `System.CommandLine` or Spectre.Console only when the command surface justifies it.
    - Keep `Program.cs` thin: test the command handler, or a `Run(args, stdout, stderr)` seam, and assert exit code and output with `dotnet test --filter`, including a non-zero exit and a stderr message on bad input.
    
    ## References
    
    - [testing.md](references/testing.md): read when adding or reshaping tests, or when `dotnet test` is slow.
    - [linting.md](references/linting.md): read when changing `dotnet format`, analyzers, or warning policy.
    
    Done when the relevant build/test/lint checks pass on what you changed, or you name each check that did not run and why.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related