2012-01-17 16 views
7

可能重複:
Catching specific vs. generic exceptions in c#C#異常處理,使用哪個catch子句?

下面是一個例子方法

private static void outputDictionaryContentsByDescending(Dictionary<string, int> list) 
{ 
    try 
    { 
     //Outputs entire list in descending order 
     foreach (KeyValuePair<string, int> pair in list.OrderByDescending(key => key.Value)) 
     { 
      Console.WriteLine("{0}, {1}", pair.Key, pair.Value); 
     } 
    } 
    catch (Exception e) 
    { 
     MessageBox.Show(e.Message, "Error detected", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

我想知道從剛剛Exception除了使用什麼例外條款,如果有一個在使用更具體的catch子句方面具有優勢。

編輯:O.k感謝大家

回答

2

一個例外,我在你的例子中看到的唯一可能的原因是,如果list爲null。 OrderByDescending()應該返回一個空的IEnumerable<>而不是空引用。

如果我沒看錯,它可能會更有意義趕上NullReferenceException

try 
{ 
... 
} catch (NullReferenceException exception) 
{ 
    MessageBox.Show(...); 
} 

然而,這真的取決於你的應用程序的需要。如果您的意圖只是提醒用戶或記錄所有例外情況,那麼捕捉Exception類就沒有問題。如果您需要爲不同類型的異常的特殊處理 - 如發送電子郵件警報,而不是僅僅記錄的消息 - 然後是有意義的使用特定的異常類型:

try 
{ 
} 
catch(NullReferenceException e) 
{ 
//... 
} 
catch(StackOverflowException e) 
{ 
//... 
} 
catch(Exception e) 
{ 
/// generic exception handler 
} 
+0

如果'list'爲null,'outputDictionaryContentsByDescending'應拋出'ArgumentNullException' – 2014-01-06 16:43:26

7

捕捉各個類型在聲明例外的將允許您處理每一個不同的方式。

Exception的一攬子規則可能對記錄和重新拋出異常很有用,但對於實際處理您可能能夠從中恢復的異常來說並不是最佳選擇。

try 
{ 
    // open a file specified by the user 
} 
catch(FileNotFoundException ex) 
{ 
    // notify user and re-prompt for file 
} 
catch(UnauthorizedAccessException ex) 
{ 
    // inform user they don't have access, either re-prompt or close dialog 
} 
catch(Exception ex) 
{ 
    Logger.LogException(ex); 
    throw; 
} 
4

您應該只有真正趕上你是例外期待代碼可能會拋出。這樣,如果它拋出了你沒有想到的東西,它可能是關鍵的東西; 應該鼓起調用堆棧並可能導致應用程序崩潰;或者你沒有想到的東西。

例如,您可能希望處理I/O代碼拋出的IOException,以便您可以將問題傳遞給用戶。然而,相同的操作可能會拋出更重要的東西,如AccessViolationException。在這種情況下,您可能希望程序終止,或以不同的方式處理問題。

通用異常處理應該只有確實用於您不關心發生了什麼錯誤,並且隨後不希望它影響您的其餘進程的情況。

1

既然你正在處理一個字典..然後你想看看這兩個例外

  • keyValuePair的關鍵是空引用(在Visual Basic中爲Nothing)。

  • ArgumentException字典中已存在具有相同鍵的元素(TKey,TValue)。

    KekValuePair Exception 這是從MSDN網站

+0

哦,感謝您的不知道它列出的可能excpetions MSDN上 – Elliot678 2012-01-17 17:56:45

0

使用,你可能期望,但仍然無法阻止,並且可以充分地處理異常類型採取。讓其他任何東西冒泡到某個可能期望它或可以處理它的地方。

在你的情況下,如果字典爲空,我可能會想到碰到NullReferenceException但我不會理解它。這是我可以驗證對代替

if (dictionary != null) 

因此沒有理由允許例外,甚至發生。切勿使用控制流程的例外情況,並根據已知的原因進行驗證。

0

根據錯誤,某些類/方法會拋出不同的異常。例如,您可能正在使用File類將數據寫入文件。您可以爲可以從中恢復的異常類型編寫多個Catch語句,並且可以使用一個通用的Exception catch來記錄並喚醒無法從中恢復的任何內容。

0

通過使用異常,您可以捕獲所有異常。你使用IOException或StackOverflowException,你只會捕獲該類型的錯誤。

由異常逮住仍持有相同的消息一StackOverflowException堆棧跟蹤等

1

你應該總是捕捉異常與具體儘可能地上課。

如果您知道如果文件被鎖定應如何處理,但您認爲所有其他錯誤都是意外且無法處理的,則應該捕獲System.IO.IOException並處理該錯誤。你應該只趕上Exception(或只是catch {)優雅退出。

2

使用哪種異常取決於try塊中的代碼。一般而言,您希望捕獲您可以執行某些操作的異常,並讓異常無法移至高級別的代碼中,您可以在其中執行某些操作。我看到人們犯的最常見的錯誤之一就是試圖找出他們無法處理的錯誤。

例如

Void ChoseFile() 
{ 
    try 
    { 
     string FileName = GetInputFile() 
    }  
    catch(InvalidFileSelectedException ex) 
    { 
     //In this case we have some application specific exception 
     //There may be a business logic failure we have some ability 
     //to infomr the user or do an action that makes sense 
    } 
    catch(FileNotFoundException exfilenot found) 
    { 
     //In this case we can do somthing different the the above 
    } 
    catch(Exception) 
    { 
     //Normal I would not use this case we have an error we don't know what to do 
     //with. We may not have a usefull action. At best we can log this exception        
     // and rethrow it to a higher level of the application that can inform the user 
     // fail the attempted action. Catching here would only suppress the failure. 
     } 

} 
0

異常處理理念 我相信你可以找到許多其他哲學

代碼防守。捕捉異常比首先防止錯誤更昂貴。

不要捕捉異常並且不要處理它。你可以花很多時間試圖找到一個被壓制的錯誤。

做記錄錯誤,你趕上。 這有助於分析問題。您可以檢查是否有多個用戶遇到相同的問題 我更喜歡用於記錄日誌的數據庫,但平面文件或事件日誌也適用。 數據庫解決方案最容易分析,但可能會引入其他錯誤。

如果錯誤是由於用戶輸入錯誤的數據造成的,請通知用戶該問題並允許它們重試。 如果他們無法解決問題,請始終允許逃生路線。

將錯誤儘可能接近源地捕獲 這可能是數據庫過程,數據訪問層(DAL)中的方法或其他位置。

處理異常與捕捉異常不同。您可能需要重新拋出異常,以便可以在堆棧或用戶界面中處理更高的異常。

重新排除異常可以用至少兩種方法完成。 自己扔不會改變堆棧。投擲前不會改變或添加到堆棧中,沒有任何好處。

有時最好不要發現異常,而是讓它冒出來。

如果您正在編寫沒有用戶界面(UI)的服務(網頁或窗口),則應始終記錄該錯誤。 同樣,這樣可以讓某人分析日誌或數據庫文件以確定發生了什麼。

您總是希望有人知道發生了錯誤。

對於try塊有很多catch語句會使代碼更難維護,特別是如果catch塊中的邏輯複雜。 相反,代碼防守。

請記住,您可以在catch塊內設置try catch塊。

另外,不要忘記在適當的地方使用finally塊。 例如,關閉數據庫連接或文件句柄等

HTH HARV