mirror of
https://github.com/alirezarezvani/claude-skills.git
synced 2026-09-09 22:31:29 +00:00
- Extract commun languages rules in a separate rules/universal.md containing all cross-language rules in one place - Move language-specific rules inline into each languages/*.md file, organised into consistent sections: Security / Async / Resource Management / Exception Handling / Performance / Idioms - Add Java support: languages/java.md with full section coverage - Every review now requires exactly 2 file reads: universal.md + one language file - Add "Adding a new language" guide to SKILL.md: one file to create, nothing else changes
3.9 KiB
3.9 KiB
| language | extensions | ||||
|---|---|---|---|---|---|
| csharp |
|
C# / .NET — Language-Specific Review Notes
Load this file alongside rules/universal.md. Universal rules are not repeated here — only C#-specific rules and idioms.
PR Analyzer — C# Risk Signals
#pragma warning disableand[SuppressMessage]— verify they are justifiedunsafe { }blocks — require explicit sign-off- Null-forgiving operator (
!) used broadly without justification dynamicused outside of interop scenarios- Hardcoded connection strings in source files
Code Quality — C# Checks
async voidmethods (except event handlers)Taskreturned but not awaitedIDisposableobjects not inusing/using var- Bare
catch { }orcatch (Exception e) { }swallowing silently - Nullable reference types feature disabled at project level
Security
- Flag raw string interpolation in SQL queries — require parameterized queries (
SqlCommand) or EF Core - Flag missing
[ValidateAntiForgeryToken]on state-changing controller actions - Flag user-controlled data passed to
Process.Start()orFileAPIs without validation - Flag hardcoded connection strings — require
appsettings.json+ secrets management - Flag
[AllowAnonymous]on endpoints that should be protected
Async / Await
- Flag
async voidmethods outside of event handlers — cannot be awaited and swallow exceptions - Flag
.Result,.Wait(), or.GetAwaiter().GetResult()onTask— causes deadlocks in ASP.NET contexts - Flag missing
ConfigureAwait(false)in library (non-application) code - Flag
Task.Run()wrapping synchronous code inside ASP.NET request handlers unnecessarily - Flag
CancellationTokennot threaded through to downstream async calls
Resource Management
- Flag
IDisposableobjects (SqlConnection,HttpClient,FileStream, etc.) not wrapped inusing/using var - Flag
HttpClientinstantiated withnewinside a method — useIHttpClientFactoryor a shared static instance to avoid socket exhaustion - Flag
DbContextregistered as a singleton in DI — it must be scoped - Flag
MemoryStream/MemoryCachegrowing unboundedly without eviction policy
Exception Handling
- Flag
catch { }orcatch (Exception) { }with no logging or re-throw — silent swallow - Flag
catch (Exception e) { throw e; }— resets the stack trace; usethrow;instead - Flag catching
Exceptionwhen a specific type (IOException,HttpRequestException) is appropriate - Flag exception filters (
when) used for side effects that suppress the exception - Flag exceptions used for control flow in hot paths — use
Try*pattern methods instead
Performance
- Flag
.ToList()/.ToArray()onIQueryablebefore filtering — forces all rows into memory; filter server-side first - Flag
stringconcatenation in loops — useStringBuilder - Flag
Enumerable.Count()onIQueryablewhen only an existence check is needed — useAny() - Flag
awaitin a loop whereTask.WhenAll()would parallelize the work - Flag synchronous file or network I/O in an
asyncmethod — use the async overload
Idioms and Best Practices
Null Safety
- Ensure
<Nullable>enable</Nullable>is set in the project file - Flag excessive use of
!(null-forgiving) without a comment explaining why - Prefer
is null/is not nullover== nullfor null checks
LINQ
- Flag
First()whereFirstOrDefault()is safer - Flag complex LINQ chains that would be clearer as explicit loops
Modern C# (10+)
- Prefer
recordtypes for immutable data carriers - Prefer
switchexpressions overswitchstatements where a value is returned - Prefer primary constructors (C# 12) for simple dependency injection
- Prefer file-scoped namespaces (
namespace Foo;) over block-scoped - Prefer
ispattern matching over explicit casts