Skip to content

About

C# Code smells samples and proposed solutions

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

Code Smells: a hands-on catalog in Python, C#/.NET, React + TypeScript, Go and Angular

Code Smells — a hands-on catalog in Python, C#/.NET, React + TypeScript, Go and Angular

CI CodeQL OpenSSF Scorecard Latest release License: MIT Conventional Commits

Python 3.11+ .NET 8 React 19 TypeScript 5 Go 1.24 Angular 22

"If it stinks, change it." — Kent Beck

An educational repository with 198 code smells organized in 18 categories, each one with:

  • 📖 An explanation page: definition, symptoms, causes, consequences, example, solution, recommended refactorings, exceptions, related smells, automatic detection and references.
  • 💻 Implementations in 5 languages (generic smells) or in their own language (idiomatic smells): a smelly version (with the smell, marked with SMELL: comments) and a refactored version (the fix, with REFACTOR: comments naming the technique applied).
  • ✅ Tests proving both versions behave the same — or exposing the bug hidden behind the smell.

Contents

# Category Smells Origin
01 Bloaters 5 Fowler, Mäntylä
02 Object-Orientation Abusers 6 Fowler, Clean Code
03 Change Preventers 4 Fowler, Kerievsky
04 Dispensables 7 Fowler, Clean Code
05 Couplers 9 Fowler 1999/2018, Clean Code
06 Data Dealers 6 Fowler 2018, Jerzyk
07 Functions & Conditional Logic 8 Clean Code, Jerzyk
08 Error Handling 5 Clean Code, Jerzyk
09 Comments (C1-C5) 5 Clean Code
10 Names (N1-N7) 10 Clean Code, Fowler, Jerzyk
11 General (G1-G36) 14 Clean Code, Kerievsky, Jerzyk
12 Test Smells (T1-T9) 11 Clean Code, Meszaros, van Deursen
13 Environment (E1-E2) 2 Clean Code
14 Python-specific 20 PEP 8, Pylint, Little Book of Python Anti-Patterns
15 C# / .NET-specific 20 Microsoft, D. Fowler, M. Seemann
16 React + TypeScript-specific 22 react.dev, typescript-eslint
17 Go-specific 22 Effective Go, Code Review Comments, 100 Go Mistakes
18 Angular-specific 22 angular.dev, RxJS, angular-eslint
Total 198

➡️ Full catalog with every smell and link

Where to start

  1. Introduction: what a code smell is, history and taxonomies
  2. Full catalog
  3. Repository conventions
  4. Per-language indexes: Python · C# · React + TS · Go · Angular

Layout

.
├── catalog.json              # Single source of truth (generated from tools/catalog_data.py)
├── docs/
│   ├── INTRODUCTION.md
│   ├── CATALOG.md            # Generated
│   ├── CONVENTIONS.md
│   └── smells/<NN-category>/<slug>.md
├── python/code_smells/<category>/<slug>/        smelly.py · refactored.py · test_*.py
├── csharp/src/CodeSmells/<Category>/<Slug>/     Smelly.cs · Refactored.cs
│   └── tests/CodeSmells.Tests/<Category>/       <Slug>Tests.cs (xUnit)
├── react-ts/src/smells/<category>/<slug>/       Smelly.tsx · Refactored.tsx · *.test.tsx (Vitest)
├── go/smells/<category>/<slug>/                 smelly/ · refactored/ (with _test.go)
├── angular/src/smells/<category>/<slug>/        smelly.ts · refactored.ts · *.spec.ts (Vitest + TestBed)
└── tools/                    # Catalog generation and verification

Running the examples

Requirements: Python 3.11+ with pytest, .NET 8 SDK, Node 22.22+ and Go 1.24.

make all          # everything: catalog + the 5 languages
make python       # cd python   && python3 -m pytest
make csharp       # dotnet test CodeSmells.sln (repo root)
make react-ts     # cd react-ts && npm ci && npm run check
make go           # cd go       && go vet ./... && go test ./...
make angular      # cd angular  && npm ci && npm run check

The GitHub Actions workflow (.github/workflows/ci.yml) runs the same checks on every push.

Quality gates

Smelly code is bad on purpose, so every linter and analyzer is switched off for smelly files only. Everything else — refactored code, the production code behind the test smells, and the clean tests — must pass the same gates locally and in CI:

Area Checks
Catalog generated files up to date, every smell has docs + 4 implementations, no broken Markdown links
Python Ruff (lint + format), mypy --strict, pytest with branch coverage
C# / .NET warnings as errors, .NET analyzers latest-recommended, code style enforced in build, NuGet lock files
React + TS TypeScript strict, Vitest + Testing Library with coverage, npm audit
Go gofmt, go vet, go test -race with coverage
Angular strictTemplates + extended diagnostics as errors, Vitest + TestBed with coverage, production build, npm audit
Security CodeQL (C#, Python, Go, JS/TS + workflows), OpenSSF Scorecard, Dependabot, SHA-pinned actions, least-privilege tokens

Formatting is shared through .editorconfig and line endings through .gitattributes.

Adding a new smell

  1. Add it to tools/catalog_data.py and run python3 tools/build_catalog.py.
  2. Write its page at the doc path listed in catalog.json.
  3. Implement smelly + refactored + tests at every code path.
  4. python3 tools/check_catalog.py --strict must finish with no missing items.
  5. Commit using Conventional Commits.

See CONTRIBUTING.md for the full workflow.

Community

Sources

Fowler & Beck, Refactoring (1999, 2018) · Martin, Clean Code (2008, ch. 17) · Kerievsky, Refactoring to Patterns (2004) · Mäntylä & Lassenius (2006) · Meszaros, xUnit Test Patterns (2007) · Jerzyk & Madeyski, codesmells.org (2023) · Refactoring.Guru · Martin Fowler — CodeSmell · official documentation of each language. See the Introduction.

Back to top ↑

About

C# Code smells samples and proposed solutions

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages