2011-04-02 79 views

回答

0

Exceptin處理是一種機制,可以防止從一種方法向另一種方法返回(不良)結果,並隔離結果中的例外。

例如,您可以從UI調用您的類庫(名爲A)的方法,然後A調用B和B調用C.現在C方法(運行時異常)中存在運行時問題。你可以給B回報,然後說嘿!這裏有一個錯誤,那麼B應該對A和A執行相同的操作... 你看!你可以在C中拋出一個異常,然後你不需要在B中捕獲它。然後,當在一些上層調用A方法時,你只需要放一個try-catch塊,只需報告錯誤而不需要額外添加if聲明。當然,有些情況下你必須把你的try-catch塊放到你的類庫中(例如,當你遇到一個只涉及你的類庫而不是更高層的異常時)。

根據我的經驗,抓魚應放置在最接近用戶界面的地方,您可以用最簡單的方式報告抓魚。因此,「投擲陳述」應該超過你的課堂圖書館中的「投擲陳述」。

當然,您可以實現自己的Exception類以獲得更好的錯誤處理(請參閱here)。

0

而且,在與外部服務通話時,只能使用try/catch,而您無法控制結果。否則,當你有控制,你應該避免造成異常和有一個「返回null」的方式在沒有對象可等只是一個設計技巧;)

+0

如果您的方法條件中存在錯誤,例如,如果您在期待某個對象時傳遞null值,或者您要求爲某個對象提供一個鍵,並且您得到的鍵不是一個已知的鑰匙。這是你想要陷入並引發異常的東西,因爲這不應該發生。返回null可能沒有用處,可能會將問題推遲到稍後診斷更加困難,因爲它不再接近問題的根源。 – 2011-04-02 10:26:02

2

接聽正是到你的要求,使用try-catch塊到處理的例外,所以你應該把它們放在你實際上將處理異常

這可有點微妙,所以讓我把一些例子:假設你有一些方法做一個文件的東西,並以文件的路徑給出一個參數。在這種情況下可能會發生許多不好的事情:

如果找不到文件,或者它不能被打開(例如:權限問題,某些程序被阻止等),那麼這是調用者的而不是被調用者的錯誤以及產生的異常已經是對問題的描述:讓它傳播。

如果文件不是預期的格式(例如,因爲應該有一個號碼,但沒有這個號碼,你會得到一些int.Parse()調用失敗),它仍然是調用者的錯誤(它向你傳遞了一個壞的路徑文件,怎麼意思!),但內部的例外不是問題的準確性;這裏的catch-wrap-throw模式效果最好:你捕獲異常,包裝它變成一個更具描述性的異常類型(即,創造良好的類型的新的異常,並把舊的,因爲它是InnerException),並拋出一句:調用者不關心代碼中的哪個任務失敗,它應該關心爲什麼失敗。

現在,讓我們調整的情形有點在最後一種情況:假設你的庫嘗試讀一些可選的配置文件,在預先定義的位置。如果加載任何這些失敗,該異常應該由庫本身處理,回落到使用默認選項或其他。

總結:如果異常是調用者的做錯事的直接後果,讓它傳播。如果是間接結果(例如,將路徑傳遞給錯誤的文件),請使用catch-wrap-rethrow來告訴調用者它做了什麼錯誤,而不是它如何破壞您的代碼邏輯。如果這是一個信號,表示您能夠處理的異常但可預見的情況,那麼您只需處理它。除此之外,你可以在一些方法開始做一些「健全檢查」和預防性拋出一個描述性異常時知道一些參數的值作祟,而不是等待實際而發生的問題(因此這是早期發現問題時catch-wrap-rethrow的替代方案)。

回到客戶端代碼(使用您的代碼API),應該處理異常ASAP。儘快採取:儘快,但不是之前它實際上是可能的。例如,一個函數作爲另一個函數(「自制」咖喱)的包裝,不應該嘗試處理由傳遞的參數觸發的異常,除非它實際上可以解決問題並重試。示例(非常通用):

void DoSomethingEasily(object someArgument) { 
    MyAPI.DoSomething(someArgument, "some-predefined-string-argument"); 
} 
// ... somewhere else on the code ... 
    DoSomethingEasily(myObject); 

在這種情況下,處理異常從MyAPI.DoSomething可以拆分工作:如果異常是由"some-predefined-string-argument"單獨引起的,那麼它的DoSomethingEasily的工作來處理它。如果異常是由myObject引起的,那麼DoSomethingEasily不應該搞亂,讓外碼處理自己的麻煩。

如果有一些未由參數引起的異常(例如,由API的一些狀態引起的,或由外部因素如未能的裝置),所述儘快想法再次適用:如果DoSomethingEasily具有足夠的信息/背景能夠處理這些案件,那麼它絕對應該。然而,如果它不能,那麼最好不要阻礙,因此調用它的代碼有機會處理這個問題。


獎金的建議:不管情況(原因),API拋出的任何異常應始終記錄。如果您正在使用C#與Visual Studio IDE,然後它是相當建議使用內置的XML註釋文檔格式,所以異常(和其描述)將出現在智能感知的提示。

希望這會有所幫助。