2012-03-15 215 views
4

我有一些代碼這樣爲什麼try塊需要一個catch

try 
{ 
    result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value; 
} catch { } 

現在,我不知道在調用此呼籲,如果我要尋找的屬性存在(好醇的SharePoint之前)。

因此,我可以編寫我想要創建的代碼的唯一線性方式就是這樣。

try 
{ 
    result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value; 
} catch { } 
try 
{ 
    result.LastName = nodes[myIdx].Attributes["ows_LastName"].Value; 
} catch { } 

.... 

現在我沒有使用這段代碼的catch部分,並最終導致大量完全冗餘的行。

爲什麼我不能只是做

try { result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value; } 

那麼,爲什麼我們明確被迫宣佈,即使沒有被處理的catch塊?我確信有一個很好的理由,但不能解決它。

編輯:在大家開始關注吞嚥異常是不好的,等等等等。我們(和我)都知道這些論點,但在這個(和許多)現實世界的場景中,沒有什麼例外,我無法做(或需要做)來解決這個問題。

+1

閱讀[文章] [1] [1]:http://stackoverflow.com/questions/1573130/net-throwing-custom-exceptions – CheGueVerra 2012-03-15 02:20:47

+0

@CheGueVerra - 不知道如何自己相關的我的問題? – 2012-03-15 02:22:03

回答

5

的他們是不是多餘的 - 他們有一個特定的目的。默認情況下,缺少catch塊會將異常重新拋出到調用方法。一個空的catch塊實質上「吞食」了異常並讓程序繼續,忽略了是否引發了異常;通常是一種不好的做法

根本就沒有任何特別之處異常

它可能是真實的一個類型的異常的可能不是「例外」在這種情況下,但是這不是異常可能發生。您應該處理該例外並適當處理任何其他問題。

例如 -

如果nodes爲空?如果myIdx超出nodes陣列的範圍,該怎麼辦?這兩個條件中的任何一個都是例外,您應該專門處理它們或讓調用程序處理它們並採取適當的行動。

[有]什麼我可以做(或需要做的)來修復行爲

你可能不能夠修復,但你可能需要的知道它。在這種情況下,程序的行爲有什麼不同?記錄消息?發出警告?設置默認值?什麼都不做可能是一個合適的答案,但很有可能不是對任何可能的異常的適當迴應。

+0

現在這是我見過的第一個合理的答案。我沒有考慮如果發生另一種類型的例外情況,我會吞嚥的情況(雖然在我的例子中並沒有真正相關,但肯定會採用)。感謝您的意見。 – 2012-03-15 02:36:33

6

如果你想吞下異常(catch它但什麼都不做),你必須明確地這樣做。

這通常是不好的做法,所以沒有理由提供一個語法快捷方式。您通常應該:

  1. 以某種方式處理異常。這可能意味着:
 
a. Retry 
b. Rethrow it (preserving the inner exception) with a more meaningful message. 
c. Do it another way. 
d. Log it (though logging and rethrowing might be better). 
e. Other 

2.  就讓它泡了(沒有嘗試,或只是嘗試/最後)。

1

try/catch塊的設計顯式用於捕獲和處理拋出應用程序中的異常。

簡單地吞下異常通常是一個壞主意(即使您只是記錄異常),並且必須明確地完成。

2

推理可能是因爲你不應該捕捉異常,如果你不能處理它。如果沒有相應的catch,允許您登錄try將無能爲力,只會導致最糟糕的做法。

至於您所引用的特定代碼,難道您不能在嘗試訪問索引器之前進行空檢查嗎?

+0

請參閱我對Simon Wang和Xander的回覆我的具體代碼 – 2012-03-15 02:32:41

1

它是語言語法的一部分。如果沒有至少一個catchfinally,您不能try。沒有獨立的try,只有try-catchtry-finallytry-catch-finally

它根本沒有任何意義try一些代碼,如果你不打算理會處理異常(catch),或至少確保一些後續代碼始終運行,無論發生了什麼(這是finally)。

+0

想必他是問爲什麼這是語法。 – 2012-03-15 02:24:21

4

爲什麼不只是檢查項目是不是null

if(nodes[myIdx].Attributes != null && 
    nodes[myIdx].Attributes["ows_FirstName"] != null) { 
    /* ... your code ... */ 
} 

或者:

if(nodes[myIdx].Attributes != null) { 
    if(nodes[myIdx].Attributes["ows_FirstName"] != null) { 
     /* ... your code ... */ 
    } 
    if(nodes[myIdx].Attributes["ows_LastName"] != null) { 
     /* ... your code ... */ 
    } 
} 
+0

由於sharepoint XML webservices具有簡單地忽略空值而非提供空值的特性的奇妙行爲。 – 2012-03-15 02:29:27

+0

@MaximGershkovich我的更新答案是否可用? – xandercoded 2012-03-15 02:32:21

+1

這是一個很好的解決方案。 – tsells 2012-03-15 02:39:38

1

這幾乎已經在這個問題回答說:C#: should all exceptions be caught

基本上,如果你正在追趕它,那麼你應該用它做什麼,否則不要抓它。在你的情況下,爲什麼你不能檢查屬性值是否先存在?

2

必須有另一種方式來檢查,如果存在的屬性或沒有,你不應該使用異常處理一些功能性的目的,你這樣的代碼:

try 
{ 
    newstring = oldString.ToString(); 
} 
catch{} 

你應該做的是:

if(oldString != null) 
{ 
    newstring = oldString; 
} 

請記住,try catch是用於處理名爲'exception'的東西

+0

Sharepoint XML webservices簡單地省略了空值而不是空值的屬性。這意味着對於每一個數據子集(IE:每行),我都需要運行數據並檢查。在我看來,簡單地允許例外發生(雖然有爭議)更實際。 – 2012-03-15 02:31:25

0

您不應該有空的catch塊。這是糟糕的編程習慣。

讓我想起了經典的ASP On Error Resume Next

1

看起來您正在使用SharePoint Web Services之一,所以返回類型是某種XmlElement?我很確定有一種方法來檢查是否存在一個屬性,這比拋出異常更便宜。

另外,你需要一個幫助器方法來封裝檢查和數據檢索。

+0

我不相信有一種方法來檢查XmlAttributeCollection(我看過,但可能是錯誤的),但即使有我仍然會爭辯說,有這種情況下,這種語法將是適當的。 – 2012-03-15 02:34:32