dotnet-csharp-code-smells
dotnet-csharp-code-smells
Proactive code-smell and anti-pattern detection for C# code. This skill triggers during all workflow modes -- planning, implementation, and review. Each entry identifies the smell, explains why it is harmful, provides the correct fix, and references the relevant CA rule or cross-reference.
Cross-references: [skill:dotnet-csharp-async-patterns] for async gotchas, [skill:dotnet-csharp-coding-standards] for naming and style, [skill:dotnet-csharp-dependency-injection] for DI lifetime misuse, [skill:dotnet-csharp-nullable-reference-types] for NRT annotation mistakes.
Out of Scope: LLM-specific generation mistakes (wrong NuGet packages, bad project structure, MSBuild errors) are covered by [skill:dotnet-agent-gotchas]. This skill covers general .NET code smells that any developer -- human or AI -- should avoid.
1. Resource Management (IDisposable Misuse)
| Smell | Why Harmful | Fix | Rule |
|---|---|---|---|
Missing using on disposable locals |
Leaks unmanaged handles (sockets, files, DB connections) | Wrap in using declaration or using block |
CA2000 |
Undisposed IDisposable fields |
Class holds disposable resource but never disposes it | Implement IDisposable; dispose fields in Dispose() |
CA2213 |
| Wrong Dispose pattern (no finalizer guard) | Double-dispose or missed cleanup on GC finalization | Follow canonical Dispose(bool) pattern; call GC.SuppressFinalize(this) |
CA1816 |
| Disposable created in one method, stored in field | Ownership unclear; easy to forget disposal | Document ownership; make the containing class IDisposable |
CA2000 |
using on non-owned resource |
Premature disposal of shared resource (e.g., injected HttpClient) |
Only dispose resources you create; let DI manage injected services | -- |