C# 從基礎到精通 — 第 7 講
使用異常和 IDisposable 管理資源生命週期
該部落格上撰寫的文章是出於教學目的而創建的。 另外,文章中的資訊可能不正確,請謹慎。
可能失敗的程式碼必須設計為包含失敗後的狀態。 重要的是,不僅要捕獲異常,還要確保文件和連接等資源組織在任何路徑中。
可預測的故障
bool TrySpendGold(int amount)
{
if (amount < 0 || Gold < amount)
{
return false;
}
Gold -= amount;
return true;
}
經常出現的結果(例如缺少黃金)可以表示為 bool 或單獨的結果類型。 異常用於當前流程中難以正常處理的故障,例如文件損壞或違反合約。
例外處理
try
{
string json = File.ReadAllText(path);
settings = JsonSerializer.Deserialize<Settings>(json)
?? throw new InvalidDataException("Settings are empty");
}
catch (IOException error)
{
logger.Log(error.Message);
settings = Settings.CreateDefault();
}
僅捕獲可以處理的異常,然後恢復或傳遞更有意義的資訊。 如果您捕獲所有異常而不處理其內容,則錯誤可能會悄悄隱藏。
I一次和使用
using FileStream stream = File.OpenRead(path);
using var reader = new StreamReader(stream);
string text = reader.ReadToEnd();
當它超出使用範圍時,就會呼叫 Dispose。 除了正常回傳之外,也會從發生異常的路徑中清除檔案句柄。
GC 回收託管物件的內存,但不承諾立即關閉檔案、套接字或本機緩衝區。 擁有這些資源的類型必須提供 IDisposable 合約。
稍後替換狀態
Settings LoadSettings(string path)
{
string json = File.ReadAllText(path);
return JsonSerializer.Deserialize<Settings>(json)
?? throw new InvalidDataException("Invalid settings");
}
Settings loaded = LoadSettings(path);
currentSettings = loaded;
如果您完全建立新設定並將其替換為現有設置,則即使載入過程中出現故障,現有狀態也將保留。 異常處理的目的是使失敗前後的狀態和資源生命週期比捕獲次數更可預測。