Agent Skills: C# /.NET Development

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

UncategorizedID: alexei-led/claude-code-config/writing-csharp

Install this agent skill to your local

pnpm dlx add-skill https://github.com/alexei-led/cc-thingz/tree/HEAD/src/skills/writing-csharp

Skill Files

Browse the full folder contents for writing-csharp.

Download Skill

Loading file tree…

src/skills/writing-csharp/SKILL.md

Skill Metadata

Name
writing-csharp
Description
Idiomatic C# /.NET development. Use when writing C# code, changing `.csproj`

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.