前言
統一的程式碼風格能大幅降低認知負荷、提升團隊協作效率、減少合併衝突。本文整理涵蓋檔案組織、縮排換行、命名慣例、註解規範、宣告與陳述式風格、工程化習慣的完整規範,參考 Microsoft 官方指南與社群共識,適合作為團隊編碼標準基準。
一、檔案與目錄組織
- **單一類別單一檔案**:檔名與類別名一致 (`UserService.cs`)。
- **檔案長度** 建議 < 2000 行,超過拆分部份類別或抽離功能。
- **目錄對應命名空間**:`MyProject/Services/UserService.cs` ↔ `MyProject.Services`。
- **專案結構**:`src/` (主程式)、`tests/` (測試)、`docs/` (文件)、`build/` (建置腳本)。
二、縮排、換行與空白
| 規則 | 說明 | 範例 |
| 縮排字元 | **Tab** (非空白),IDE 設定 Tab = 4 字元寬度 | — |
| 換行原則 | 逗號後、運算子後、高層優先;折行對齊上一層起始位置 | var r = a * b / (c - g + f) + 4 * z; |
| 方法呼叫換行 | 參數過多時,每行一參,左括號後換行 | DoSomething(arg1, arg2, arg3); |
| 大括號風格 | **Allman 風格** (大括號獨佔行,與關鍵字對齊) | if (cond) { // ... } |
| 空行用途 | 類別/介面間 2 空行;成員/方法/屬性間 1 空行;方法內邏輯區塊 1 空行 | — |
| 運算子前後 | 二元運算子前後各一空白;一元運算子不加 | a = b + c; ++i; |
| 表格式對齊 | 相關宣告區塊以空白對齊 `=`、`:`,提升可讀性 | string name = "Ed"; int age = 30; |
三、命名慣例總表
| 元素 | 大小寫 | 前綴/後綴 | 範例 |
| 類別/結構/介面/列舉/委派/事件/命名空間 | PascalCase | 介面加 `I` 前綴 (`IEnumerable`) | `UserService`, `IRepository`, `OrderStatus` |
| 公共/受保護欄位/常數/唯讀靜態欄位 | PascalCase | — | `MaxConnections`, `DefaultTimeout` |
| 私有/內部欄位 | _camelCase | 底線前綴 `_` | `_connectionString`, `_cache` |
| 參數/區域變數 | camelCase | — | `userId`, `totalCount` |
| 方法/屬性 | PascalCase | 動詞/動詞片語 (`GetUser`, `CalculateTotal`) | `GetUserById`, `FullName` |
| 事件處理常式 | PascalCase | `EventHandler` 後綴 (`OnClick`, `Button_Click`) | `OnUserCreated`, `btnSave_Click` |
| 泛型型別參數 | PascalCase | 單一字母 `T` 或描述性 `TEntity`、`TKey` | `T`, `TEntity`, `TKey` |
**禁用**:Hungarian 符號 (`strName`, `iCount`)、底線分隔單字 (`user_name`)、縮寫全大寫超過 2 字元 (`XmlHttp` → `XmlHttp`,非 `XMLHTTP`)。
四、註解規範
- **XML 文件註解** (`///`):所有 **public/protected** 型別與成員**必須**提供 ``、``、``、``。
- **單行註解** (`//`):解釋「為什麼」而非「做什麼」;置於程式碼上方,縮排一致。
- **區塊註解** (`/* */`):僅用於暫時註解大段程式碼或檔案標頭授權資訊。
- **TODO / HACK / NOTE** 格式:`// TODO: [Issue#123] 優化查詢效能`,便於工具追蹤。
五、宣告與陳述式風格
- **一行一宣告**,附註解說明用途:
`int retryCount; // 重試次數`
- **區域變數宣告即初始化**:
`var user = _repo.GetById(id);`
- **`using` 區塊管理 `IDisposable`**:
`using (var conn = new SqlConnection(cs)) { ... }`
- **`var` 隱含型別**:型別明顯時使用 (`var list = new List()`),否則顯式型別。
- **`switch` 表達式 (C# 8+)** 取代傳統 `switch`:
`var result = shape switch { Circle c => c.Radius * c.Radius * Math.PI, Rectangle r => r.Width * r.Height, _ => 0 };`
- **模式比對** 簡化型別檢查與轉換:
`if (obj is User u && u.IsActive) { ... }`
六、工程化習慣
- **警告視為錯誤**:專案屬性 → Treat warnings as errors = All。
- **靜態分析**:啟用 **Roslyn Analyzers** (Microsoft.CodeAnalysis.NetAnalyzers)、**StyleCop.Analyzers**、**SonarAnalyzer.CSharp**。
- **格式化自動化**:`.editorconfig` 強制統一風格,CI 檢查 `dotnet format --verify-no-changes`。
- **Git Hooks**:`pre-commit` 執行 `dotnet format`、`dotnet build`。
- **Code Review 清單**:命名、複雜度、測試覆蓋、例外處理、記錄、效能、安全性。
七、總結
規範非束縛,而是**共同語言**。團隊應將本指南納入專案 `.editorconfig`、CI 檢查與 Code Review 標準,新成員入職即可快速上手,資深成員專注業務邏輯而非風格爭論。定期回顧調整,保持規範與技術棧演進同步。