> For the complete documentation index, see [llms.txt](https://framework.aic.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://framework.aic.io/technical-guidelines-code-standards-and-tech-stack/c-code-standards/c-language-version-and-feature-policy.md).

# C# Language Version and Feature Policy

## AIC Standard

Production .NET 10 projects use C# 14.

C# 15 features may be evaluated in .NET 11 preview projects but must not enter production code unless the project is approved for that runtime and language version.

## General Language Rules

Use modern C# features when they improve clarity, safety or performance.

Do not use language features simply because they are new.

## Recommended Features

AIC encourages:

* nullable reference types
* records for immutable DTOs and value-like data
* pattern matching where it improves clarity
* `required` members where appropriate
* collection expressions where supported and clear
* primary constructors where they reduce boilerplate without hiding dependencies
* file-scoped namespaces
* implicit usings where project-wide consistency is maintained
* `using` declarations for deterministic disposal
* switch expressions for clear mappings

## Features Requiring Care

Use carefully:

* reflection
* dynamic
* source generators
* unsafe code
* custom implicit conversions
* operator overloads
* expression tree heavy code
* Native AOT-specific optimisations
* global state

## Forbidden or Restricted Practices

Avoid or prohibit:

* `async void` except event handlers
* `Task.Result` and `.Wait()` in asynchronous flows
* swallowing exceptions without logging or compensating action
* using `DateTime.Now` for persisted or cross-system time
* business logic in property getters
* mutable public static state
* service locator patterns
* public fields on domain objects
* stringly-typed security decisions

## Example: Clear Modern C\#

```csharp
public sealed record CreateCaseRequest(
    string Reference,
    string Title,
    string CreatedBy);

public async Task<Result<CaseId>> HandleAsync(
    CreateCaseCommand command,
    CancellationToken cancellationToken)
{
    if (string.IsNullOrWhiteSpace(command.Title))
    {
        return Result.Invalid("Title is required.");
    }

    var caseRecord = CaseRecord.Create(command.Reference, command.Title, command.CreatedBy);

    _dbContext.Cases.Add(caseRecord);
    await _dbContext.SaveChangesAsync(cancellationToken);

    return Result.Success(caseRecord.Id);
}
```

## Feature Adoption Rule

Before adopting a new C# feature across a project, consider:

* Does every developer understand it?
* Does ReSharper and the CI analyzer support it?
* Does it work with the target framework?
* Does it improve readability?
* Does it affect serialization, testing or tooling?
* Is there a migration risk?

Record project-wide language feature decisions in an ADR where they materially affect style.
