csharp-nrtlisted
Install: claude install-skill CloudyWing/ai-dotfiles
# C# Nullable Reference Types (NRT) 規範
當專案啟用 NRT(`<Nullable>enable</Nullable>`)時,自動套用以下規範。專案未啟用 NRT 時,不強迫修改。
## 核心原則
**用型別系統表達語意,不用假預設值消除警告。**
屬性是否 nullable、是否 required,應反映業務語意,而非為了讓編譯器安靜。
### 禁止模式
以下寫法一律禁止,除非本文件明確列出的例外情境:
```csharp
// ❌ 硬塞預設值消警告
public string Name { get; set; } = "";
public string Name { get; set; } = default!;
public string Name { get; set; } = null!;
public OrderDto Order { get; set; } = default!;
```
### 允許的預設值
集合屬性使用空集合初始化是合理的語意表達(空集合 ≠ null),不屬於「假預設值」:
```csharp
// ✅ 集合用空集合初始化
public IReadOnlyList<string> Tags { get; init; } = [];
public required IReadOnlyList<OrderItemDto> Items { get; init; } = [];
```
---
## 屬性宣告策略(依類別用途)
### DTO / Response Model
API 回傳或層間傳遞的資料物件。所有必填屬性使用 `required init`。
```csharp
public class OrderDto {
public required int Id { get; init; }
public required string CustomerName { get; init; }
public string? Note { get; init; }
public required IReadOnlyList<OrderItemDto> Items { get; init; } = [];
}
```
### Request / Input Model(API Binding、Form Binding)
ASP.NET Core Model Binding 與 `System.Text.Json` 反序列化需要 setter。必填屬性使用 `required set`。
```csharp
public class CreateOrderRequest {
public required string CustomerName { get; set; }
public required IReadOnlyList<CreateOrderItemRequest> Items { get; set; } = [];
public string? Note { get; set; }
}
```
> `System.Text.Json` 從 .NET 7 起支援 `required` keyword,反序列化時缺少必填屬性會拋出 `JsonException`。若需相容 `Newtonsoft.Json`,改用 `[JsonRequired]` attribute。
###