2011-12-07 22 views
0

這裏的主要例子是複製一個word文檔。我在我的程序中有這些代碼行:我可以/應該使用例外來錯誤檢查我的程序嗎?

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

現在我試圖建立錯誤檢查。我想確保輸出的Word文檔在我嘗試保存之前不在其他地方打開,因爲否則會引發異常。

我看到它的方式是拋出異常來警告我導致代碼的默認功能無法按預期工作的錯誤。從這個意義上講,我會很自然地發現一個異常,閱讀它來辨別問題(在這種情況下,文檔目前是鎖定/在別處打開),因此顯示MessageBox以提醒用戶他們正在嘗試的文檔寫入其他地方打開的文件。

這樣可以嗎?我看過很多地方,看看這是什麼異常設計要做的事情,而其他地方人們似乎認爲使用異常做這樣的事情對於所有編程傳統都是可怕的,寧願自己檢查一下。

什麼是總體共識?

感謝

回答

2

您應該使用例外來處理例外事件

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

該文件已被使用並被其他東西鎖定可能是一種特殊情況;它可能是,所以這可能就好了。

+0

這是一個判斷一個特殊情況是否發生的問題嗎? –

+1

這是一個判斷問題,你是否認爲潛在的發生會是「特殊」。例如:用戶輸入0除以:可預見而不是例外。互聯網連接突然失敗:例外。 –

+0

我明白了,非常感謝。 :) –

1

IMO,在.NET中,異常應該用於管理意外錯誤。

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

因此,我用幾句話來說,是爲了管理不可預見的問題而不是業務問題。用異常來處理每個業務問題的想法更多的是「超越」面向對象的方法,而不是它應該用於什麼。

你的例子是IMO使用異常的好方法的一個很好的例子。全球範圍內它只是一個「大」的嘗試/捕捉功能或特定任務。

0

AFAIK例外是專爲處理東西都是從開發商控制諸如硬件故障或斷開網絡或類似的東西,這裏的開發商可能不會有問題的知識,

恕我直言,這是更好地在表達 int r = val/divider;比來檢查DivideByZeroException

0

使用異常控制程序流是「未完成」檢查的divider值。只有當您不希望整個應用程序崩潰時,它們才應用於處理特殊情況。

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

如果沒有其他方式知道Word文件是否已經打開,我認爲您可以使用Exception來執行此操作。好事是你抓住了一個特定的例外,因爲其他事情可能會出錯。問題是IOException可能有另一個源(即目標文件夾不可訪問等)。這不僅適用於您的示例,還適用於所有(複雜)異常驅動的流程。上面給出的TryParse例子非常簡單,所以在那裏,這不是什麼問題。

結論:不要這樣做,除非它是唯一的方法。然後,嘗試用單獨的方法將其隔離。這樣,如果您找到更好的解決方案,則可以隨時更改您的實施。另外,嘗試捕捉最具體的異常,並記住異常可以有幾個來源。

0

如果一個例程可以通過正常返回來滿足其合同,它應該這樣做。如果在沒有違反合同的情況下例程無法正常返回,它應該拋出異常。如果一個例程的合同被視爲給定的,那麼在判斷例程是否應該拋出異常時,實際上沒有太多的判斷餘地。它應該根據上述簡單的規則返回或拋出。

地方判斷進入等式是決定一個例程的合同應該是什麼。一個有用的模式是提供例程的「Try」版本和「Do」版本;如果「Try」版本由於合理預期的問題而無法執行請求的操作,則它將指示通過返回某種類型的錯誤值;如果「Do」版本無法執行請求的操作,出於任何原因,它將拋出異常。

作爲一個簡單的例子,考慮「Integer.TryParse」和「Integer.Parse」。如果有一個字符串可能是也可能不是有效的數字,可以調用Integer.TryParse。 Integer.TryParse將使用返回的標誌來指示解析是否成功;無論解析是否成功,它都會很好地返回,並且調用者負責確保TryParse在嘗試使用返回值之前成功。相比之下,Integer.Parse將只在數字解析成功時纔會返回。如果該號碼無效,則Integer.Parse會拋出異常。因此調用代碼可以使用Integer.Parse返回的值,而不必檢查它是否成功;如果Integer.Parse沒有成功,它將不會返回。請注意,Integer.TryParse可能會在某些真正特殊的情況下拋出異常(例如,如果不安全的代碼已將傳入的String引用指向其他類型的對象);唯一的保證是它不會拋出合理預期的情況(例如,它傳遞了像「XYZ」這樣的字符串而不是像「123」那樣的字符串)。

對Try/Do模式的輕微改進是讓一個例程接受一個委託,如果出現錯誤,它將被調用。在許多情況下,通過代表將是過度的,並且事先很難預先決定代表應該採取的參數,但是這種方法在有關是否混淆或放棄的決定可以由外部決定的情況下是有利的因素。這種情況出現在通信場景中,其中程序對通信呃逆的適當響應可能是通知用戶該程序有困難並允許用戶點擊「取消」,但讓程序重試操作a如果用戶沒有,那麼幾次。如果必須重試的操作只是要執行的整體操作的一小部分,那麼向主線投擲異常將「永久」放棄較大的操作,而在沒有用戶交互的情況下執行重試可能會迫使用戶對於計算機放棄用戶可能知道不可能成功的操作(例如因爲電池剛剛死在他正在與之通信的設備上)而煩惱地坐着。使用回調委託可以實現最佳的用戶界面體驗,而無需將通信代碼綁定到任何特定的用戶界面實現。

相關問題