Instruction file imported from soofoove/copilot-knowledge (
.github/instructions/csharp.instructions.md). Copyright stays with the author.
Reviewed C# and .NET Guidance
Conventions and Style
- Follow existing project conventions first, then standard C# conventions.
- Apply formatting defined in
.editorconfigwhen present. - Prefer file-scoped namespace declarations.
- Use
nameofinstead of string literals when referring to member names. - Comments explain why, not what. Do not comment obvious code.
- Prefer small, maintainable changes over large refactors.
Naming
- PascalCase for types, methods, properties, constants, and public members.
- camelCase with underscore prefix (
_field) for private fields; camelCase for local variables and parameters. - Prefix interface names with
I(e.g.,IUserService). - Suffix async methods with
Async.
Visibility and Design
- Keep public API surface intentional:
private→internal→protected→public. Default toprivate. - Do not add interfaces, abstractions, or helpers that are not needed for the current task.
- Prefer records over classes for DTOs and immutable data.
- Do not wrap existing framework abstractions without clear value.
- Reuse existing methods; do not add unused code.
Nullable Reference Types
- Use nullable reference types consistently; respect
<Nullable>enable</Nullable>. - Prefer
is null/is not nullover== null/!= null. - Use
ArgumentNullException.ThrowIfNull()for null guards at public boundaries. - Avoid blanket
!null-forgiving operators. - Trust the type system — do not add null checks when the type is non-nullable.
Error Handling
- Use precise exception types (
ArgumentException,InvalidOperationException,KeyNotFoundException); never throw or catch baseException. - Do not silently swallow exceptions; log and rethrow, or let them propagate.
- Use
string.IsNullOrWhiteSpace()for string guards. - Validate external inputs at API and service boundaries; trust internal code.
Async and Cancellation
- Avoid sync-over-async patterns: no
.Result,.Wait(), or.GetAwaiter().GetResult(). - Propagate
CancellationTokenthrough the call chain; callThrowIfCancellationRequested()in loops. - Make delays cancelable:
await Task.Delay(ms, cancellationToken). - Never use
async voidexcept in event handlers. - Use
ConfigureAwait(false)in library/helper code; omit in ASP.NET Core application code. - Return
Taskby default; useValueTaskonly when profiling shows benefit.
Modern C# Features
- Use modern features when the project's TFM supports them: pattern matching, switch expressions, raw string literals, collection expressions, primary constructors, ranges/indices.
- Do not change
<LangVersion>, TFM, or SDK version unless explicitly asked. - Do not assume preview language features are available.
LINQ and Collections
- Prefer LINQ for readable data transformations; switch to direct iteration when profiling shows a bottleneck.
- Use
AsNoTracking()for read-only EF Core queries. - Prefer projection with
Select()to avoid over-fetching. - Use
Span<T>,Memory<T>, orArrayPool<T>in hot paths when profiling justifies it.
Logging
- Use structured logging with
ILoggerand message templates; avoid string concatenation. - Never log secrets, tokens, credentials, connection strings, or personal data.
- Use appropriate log levels:
Debugfor developer diagnostics,Informationfor normal flow,Warningfor recoverable issues,Errorfor failures.
Testing
- Prefer focused tests that verify one behavior; follow Arrange-Act-Assert.
- Name tests by behavior:
MethodName_Scenario_ExpectedBehavior. - Use the test framework already in the solution (xUnit, NUnit, MSTest, TUnit).
- Mock only external dependencies; prefer real implementations where possible.
- Do not emit
// Arrange,// Act,// Assertcomments. - Match existing style in nearby test files for naming and capitalization.
Security
- No hardcoded secrets; use environment variables, user secrets, or secret management.
- Validate and sanitize all external inputs.
- Use parameterized queries for all database access; never concatenate user input into SQL.
- Apply least-privilege access control.
Dependencies and Project Structure
- Check for
Directory.Build.props,Directory.Packages.props, andglobal.jsonbefore adding or updating packages. - Prefer central package management when the repo already uses it.
- Do not assume external services or MCP tools are required when local repo context is sufficient.