[英]What exceptions should I handle
我有以下代碼:
public void OpenFile(string FileName)
{
if (FileName == null)
throw new ArgumentNullException("FileName", "OpenFile: Filename is null");
List<int> readItems = new List<int>();
using (StreamReader reader = new StreamReader(FileName))
{
string line;
int batchItem;
while ((line = reader.ReadLine()) != null)
{
if (int.TryParse(line, out batchItem))
{
readItems.Add(batchItem);
}
}
}
CurrrentFile = FileName;
FileInfo f = new FileInfo(FileName);
lock (LockObject)
{
TextWriter = f.AppendText();
TextWriter.AutoFlush = true;
}
if (readItems.Count > 0)
FileOpened(readItems);
}
我正在嘗試檢測可能的問題,例如//文件名為空。
在捕獲和記錄異常的類中,我顯然有一個catch(ArgumentNullException ex)
我是否還應該捕獲StreamReader
構造函數和FileInfo
構造函數引發的可能異常?
我知道這聽起來很愚蠢,但是我想知道是否應該對拋出的異常進行顯式捕獲,然后對通用異常進行捕獲,無論是catch(Exception ex)
還是嘗試捕獲上述代碼並重新拋出自定義異常。 否則我的try / catch塊有大約12個單獨的catch語句!
通常,如果您遵循一些簡單的規則,則可以大大簡化您的異常處理代碼。
1.只有捕獲並處理異常,您才能真正做到
如果您實際上無法從異常中恢復,則根本不應該捕獲它。 讓異常冒泡到最高點(通常是用戶界面)。
當您捕獲異常時,您應該捕獲非常具體的異常,並盡可能避免通用異常處理。
try
{
DoSomeStuff();
}
catch(HolyCrapItBlewedUpException ex)
{
RecoverFromExplosion();
}
catch(Exception ex)
{
//I really have no idea what happened, and I can't do
// anything about it, but I'm going to catch the
// exception anyway cause it makes me feel better
}
上述規則有咳嗽例外,但這使我們進入了第二條規則。
2.僅將通用異常處理用於日志記錄和實現隱藏
由於您應該讓異常一直冒泡到最高層,因此任何導致異常的事情都是一個錯誤。 此時,您應該記錄該異常並向用戶顯示一些友好的消息。
try
{
DoSomeStuff();
}
catch(Exception ex)
{
//At this point it's a bug... we need to squash it!
LogException(ex);
ShowUserRecoveryOptions();
}
您可能想要執行此操作的另一個地方是為了維護API合同,並隱藏實現細節。 如果最終用戶正在調用方法,則他們可能不需要知道所有可能發生的問題,只需知道它不起作用即可。
public void MakeMeASandwich()
{
try
{
MakeCallerASandwich();
}
catch(SecurityException ex)
{
//It's still best to distinguish between certain exceptions
// as long as it makes sense to the caller.
throw new NoIWillNotMakeYouASandwichException(ex);
}
catch(Exception ex)
{
throw new SorryICantMakeYouASandwichException(ex);
}
}
3.避免像瘟疫這樣的例外!
例外應該是……例外! 在大多數情況下,您應該能夠通過簡單地預先為異常編碼來避免異常。 真正的異常應該代表您無法預測的事情。 一個簡單的示例是檢查文件是否存在。
try
{
File.Open("blah.txt");
}
catch(FileNotFoundException ex)
{
File.Create("blah.txt");
}
在那個例子中,我知道該文件可能不存在...所以我應該編寫代碼以確保這種情況幾乎不會發生。
var fileName = "blah.txt";
if(!File.Exists(fileName))
File.Create(fileName);
File.Open(fileName);
現在,仍然有可能在此處引發FileNotFoundException
,但是我們將如何處理呢? 顯然,由於發生了真正的異常,此代碼無法再對其進行任何處理。 我們可以讓異常冒泡到下一層,因為我們在這里無法做任何有意義的事情。
始終確保將一般異常(即SystemException / ApplicationException / Exception catch子句)放在最后。 因此,為明顯做好准備。 您的情況是SecurityException,FileNotFound,PathNotFound等異常。 請檢查MSDN文檔中的這些API以及它們引發的各種異常。
產生通用異常的問題是您永遠不會知道問題出在哪里,即使FxCop對此也發出警告。 如果您的catch子句更多,那么沒問題,但是只需確保您拆分並捕獲異常即可。 例如,如果我們在不同的情況下打開2個文件,則分別捕獲每個文件而不是一個文件。
我是否還應該捕獲StreamReader構造函數和FileInfo構造函數引發的可能異常?
簡而言之:知道這些異常被拋出了,您可以做一些合理的事情嗎? 如果是,請抓住他們並這樣做。 如果沒有,讓它破裂。
使用try catch如果有錯誤,您可以在catch部分捕獲它。 首先使用特定異常,然后再使用通用異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.