throw new Exception(string message);
throw new Exception(string message, Exception innerException);
throw:明確拋出例外。Exception(string, Exception):使用指定錯誤訊息與內部例外參考初始化新例外 (MSDN 定義)。innerException 封裝在新例外中,完整保留原始錯誤鏈結,利於除錯追蹤根因。BusinessRuleException),讓上層呼叫者能針對性處理。| 策略 | 程式碼範例 | 適用情境 |
|---|---|---|
| 1. 直接處理並結束 (不再拋出) | |
頂層 UI、背景工作、不需上層知情的獨立作業 |
| 2. 通知使用者/記錄後「吞掉」例外 (空 catch) | |
極少數「預期會失敗且可安全忽略」的情境 (需詳加註解) |
| 3. 記錄/轉換後 重新拋出新例外 | |
分層架構中,下層錯誤需轉譯為上層可理解的業務例外;或需保留完整呼叫堆疊供上層判斷 |
int num = Convert.ToInt32(textBox1.Text);
try
{
if (num == 0)
throw new ArgumentNullException("輸入不可為零!");
if (num == 1)
throw new Exception("輸入不可為一!");
}
catch (ArgumentNullException ex)
{
MessageBox.Show($"參數錯誤:{ex.Message}");
}
catch (Exception ex)
{
MessageBox.Show($"一般錯誤:{ex.Message}");
}
// 進階:捕獲後轉拋自訂例外
try
{
// 呼叫底層資料存取
repository.Save(entity);
}
catch (SqlException sqlEx) when (sqlEx.Number == 1205) // 死結
{
Log.Warn(sqlEx, "偵測到死結,嘗試重試...");
throw new ConcurrencyException("資料衝突,請重新整理後再試", sqlEx); // 保留 sqlEx 為 InnerException
}
catch (Exception ex)
{
Log.Error(ex, "未預期的儲存失敗");
throw; // 直接重拋原例外 (保留完整堆疊)
}
throw; 保留原始堆疊追蹤;throw ex; 會重設堆疊起點為該行,**務必使用 throw; 或封裝為新例外 (throw new MyEx(msg, ex))**。OutOfMemoryException)。catch (Exception) 吞噬所有錯誤。innerException**,除非有極強理由切斷鏈結。ApplicationException 或 Exception),讓呼叫者能精準 catch。ex.ToString() (含堆疊、內部例外),而非僅 ex.Message。finally 或 catch 中拋出新例外覆蓋原始錯誤,若必要請使用 ExceptionDispatchInfo.Capture(ex).Throw() (NET 4.5+) 保留堆疊。catch 中 throw new Exception(msg, innerEx) 的核心價值在於錯誤語境轉譯與堆疊保留。善用內部例外鏈結、自訂例外型別、精準捕獲與完整日誌,能建立可維護、可診斷的異常處理體系。