簡體   English   中英

我可以/應該使用異常對程序進行錯誤檢查嗎?

[英]Can I/Should I use exceptions to error check my program?

這里的主要示例是復制Word文檔。 我的程序中包含以下代碼行:

try
{
    File.Copy(docTemplatePath, docOutputPath, true);
}
catch (IOException e)
{
    MessageBox.Show(e.ToString());
}

現在,我正在嘗試建立錯誤檢查。 我想確保在嘗試保存之前未在其他位置打開輸出Word文檔,因為否則會引發異常。

我看到的方式是引發異常,以警告我導致錯誤的默認功能無法正常工作的代碼。 從這個意義上講,我會很樂意捕獲異常,閱讀該異常以識別問題(在這種情況下,該文檔當前處於鎖定狀態/在其他位置打開),因此顯示了一個MessageBox來提醒用戶要嘗試的文檔事實寫入在其他位置打開的文件。

這樣可以嗎? 在我研究此過程的過程中,我看到了很多地方,這似乎是異常的設計目標,而其他地方似乎人們認為使用異常來做這樣的事情,這與所有編程傳統相悖,並且寧願自己檢查一下。

總體共識是什么?

謝謝

您應該使用Exception處理異常情況

那是; 有時會出現可預見的情況:用戶輸入的文件名可能不存在,因此,例如,在嘗試加載文件之前,您的代碼應檢查File.Exists() (不依賴於異常)。

該文件已經被使用並且被其他東西鎖定可能是一種例外情況。 可能是這樣,所以可能就好了。

在.Net中,IMO應將異常用於托管的意外錯誤。

對我來說,拋出一個身份驗證錯誤(例如錯誤的密碼)異常是一個壞主意,但是使用它來管理數據庫連接錯誤則是一個好主意。

因此,簡而言之,我使用異常來管理不可預期的問題而不是業務問題。 進行所有業務問題的想法都是一種“過度”的面向對象方法,而不是它應用於的目的。

您的例子是IMO,這是使用異常的好方法的一個很好的例子。 在全球范圍內,這只是圍繞功能或特定任務的“大嘗試”。

AFAIK異常用於處理開發人員無法控制的事情,例如硬件故障或網絡斷開或類似的情況,而開發人員可能不知道該問題,

恕我直言,最好在表達式int r = val/divider;檢查divider的值int r = val/divider; 比檢查DivideByZeroException

使用“異常”控制程序流“未完成”。 當您不希望整個應用程序崩潰時,它們僅應用於處理特殊情況。

也就是說,有時需要使用異常。 我相信.NET Framework中的int.TryParse和其他TryParse方法使用Exceptions,如果不起作用則捕獲它們,然后返回false。

如果沒有其他方法可以知道是否已打開Word文件,則我認為您可以使用Exception來執行此操作。 好消息是您捕獲了特定的異常,因為其他情況可能會出錯。 問題是IOException可能有另一個源(即,目標文件夾不可訪問,等等)。 這不僅適用於您的示例,而且適用於所有(復雜)異常驅動的流。 我在上面給出的TryParse示例非常簡單,因此在這里並沒有太大的問題。

結論:請勿這樣做,除非這是您唯一的方法。 然后,嘗試使用單獨的方法將其隔離。 這樣,如果您找到更好的解決方案,則可以隨時更改實現。 另外,請嘗試捕獲最具體的異常,並記住異常可能有多種來源。

如果例程可以通過正常返回來滿足其合同,則應該這樣做。 如果例程無法在不違反其合同的情況下正常返回,則應引發異常。 如果將例程的合同作為給定的合同,那么在決定例程是否應該拋出異常時,判斷的空間就很小。 它應該根據上述簡單規則返回或拋出。

地方判斷進入方程式是在決定例​​程的合同應該是什么。 一個有用的模式是提供例程的“嘗試”版本和“執行”版本。 如果“嘗試”版本由於合理預期的問題而無法執行所請求的操作,則它將通過返回某種類型的錯誤值來指示該錯誤; 如果“執行”版本由於任何原因無法執行請求的操作,它將引發異常。

作為一個簡單的示例,請考慮“ Integer.TryParse”和“ Integer.Parse”。 如果一個字符串可能不是有效數字,則可以調用Integer.TryParse。 Integer.TryParse將使用返回的標志來指示解析是否成功;否則,返回false。 無論解析成功與否,它都會很高興地返回,並且調用方負責在嘗試使用返回的值之前確保TryParse成功。 相比之下,Integer.Parse僅在成功解析數字后才返回。 如果該數字無效,則Integer.Parse將引發異常。 因此,調用代碼可以使用Integer.Parse返回的值,而不必檢查它是否成功; 如果Integer.Parse沒有成功,則不會返回。 注意,在某些真正特殊的情況下(例如,如果不安全的代碼使傳入的String引用指向某種其他類型的對象),Integer.TryParse可能引發異常。 唯一的保證是它不會在合理預期的情況下拋出(例如,它傳遞的字符串如“ XYZ”而不是諸如“ 123”的字符串)。

對Try / Do模式的一個略微增強是使例程接受一個委托,如果出現問題,該委托將被調用。 在很多情況下,通過委托會太過分,通常很難預先確定委托應采用的參數,但是這種方法在由外部決定是混淆還是放棄的情況下可能是有利的。因素。 這樣的情況出現在通信場景中,其中程序對通信故障的正確響應可能是發出一條消息,通知用戶該程序有困難並允許用戶按下“取消”,但讓程序重試該操作。如果用戶沒有幾次。 如果必須重試的操作只占要執行的全部操作的一小部分,則在主線上拋出異常將“永久地”放棄較大的操作,而在沒有用戶交互的情況下執行重試可能會迫使用戶令人討厭的長時間坐在電腦上,使計算機放棄用戶可能知道不會成功的操作(例如,因為電池剛在與之通信的設備上耗盡了)。 使用回調委托可以提供最佳的用戶界面體驗,而無需將通信代碼綁定到任何特定的用戶界面實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM