簡體   English   中英

我應該處理哪些異常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM