Bug 不可避免,但可建立系統化防禦體系:編譯期攔截 → 執行期早期失敗 → 診斷資訊豐富 → 生產環境可觀測。
using System.Diagnostics;
public bool ProcessIterations(int numIters) {
Debug.Assert(numIters > 0, "ProcessIterations", "迭代數必須 > 0");
// 僅 Debug 版本編譯入,Release 版本零開銷
}
Debug.Assert(condition, category, message):失敗時中斷、顯示堆疊、支援附加偵錯器
[Conditional("DEBUG")] // Release 版本自動移除呼叫
private void ImOK() {
Debug.Assert(this != null, "ObjectState", "this 不可為 null");
Debug.Assert(_id > 0, "ObjectState", "Id 必須 > 0");
// 更多業務不變條件...
}
public void DoWork() {
ImOK(); // 每個公有方法入口驗證
Debug.Assert(...); // 參數契約
// 業務邏輯
}
// 類別級追蹤開關
private static readonly TraceSwitch _switch = new("MyClass", "控制 MyClass 診斷輸出");
public void Process(int n) {
Debug.WriteLineIf(_switch.TraceVerbose, $"Enter Process({n})", "CallTrace");
ImOK();
Debug.Assert(n > 0, "Process", "n > 0");
// ...
Debug.WriteLineIf(_switch.TraceInfo, $"Exit Process, result={result}", "CallTrace");
}
TraceSwitch.Level:Off / Error / Warning / Info / VerboseDebug:僅 Debug 版本編譯Trace:Debug + Release 皆編譯,生產環境可用(謹慎使用,避免效能/資安風險)app.config / web.config / MyApp.exe.config:
TextWriterTraceListener → 檔案,EventLogTraceListener → Windows 事件日誌Debug.Listeners.Add(new TextWriterTraceListener("mylog.txt"));找到 Bug 後,請勿刪除斷言/追蹤碼。 它們是未來防禦的疫苗。常見錯誤:除錯時大量加 Trace,修好後全刪,下次同類問題又盲目摸索。
CA1062 驗證參數非 null、CA2208 異常參數檢查ArgumentNullException.ThrowIfNull(.NET 6+)現代契約 API建立「契約優先、可觀測性內建」的開發習慣,讓 Bug 無處遁形、診斷零距離。