簡體   English   中英

有關C#中的異常的問題

[英]a question about exception in c#

以下是一個代碼片段:

class xxx
{

  public xxx(){}

  try
  {
    throw new Exception(InvalidoperationException);
  }
  catch(Exception x)
  {
  }
  catch(InvalidoperationException x)
  {
  }
}

任何人都可以告訴您將在此處引發哪個異常以及其背后的原因是什么。

哇,這里有很多問題。 從哪兒開始?

  1. 該代碼將無法編譯。 您定義的try-catch塊在任何方法之外,這是不允許的。 您需要將其移動到方法內部

  2. 切勿在以后的方法中拋出打算讓自己陷入困境的方法。 這通常被稱為對“流控制”使用異常,因此不建議使用。 這樣做會增加性能成本,並且當您具有拋出並捕獲其自身異常的代碼時,使用調試器監視正在拋出的異常也非常令人困惑。 如有必要,請使用布爾變量(稱為標志)進行流量控制。

  3. 始終首先捕獲派生最多的異常類。 這意味着您應先捕獲InvalidOperationException然后再嘗試捕獲Exception 您需要在已有的代碼中顛倒catch塊的順序。

  4. 實際上,您應該永遠不要捕獲System.Exception 您應該捕獲的唯一異常是您明確理解並且將能夠處理的異常。 當您僅有的信息是拋出通用異常時,您幾乎不可能知道發生了什么問題或如何處理。

    同樣,您也永遠不要從自己的代碼中拋出此異常。 選擇從基類System.Exception繼承的更具描述性的異常類,或者通過從該類繼承創建自己的異常類。


我看到其他答案正在向您顯示示例代碼,說明您的代碼應該被重寫。 我不會這樣做,因為如果我重寫您的代碼是正確的,我最終會得到以下結果:

class Xxx
{
    public Xxx()
    {

    }
}

沒有特別的幫助。

如果代碼是這樣的

 class xxx
    {

      public xxx(){

      try
      {
        throw new Exception(InvalidoperationException);
      }

      catch(InvalidoperationException x)
      {
      }

catch(Exception x){}}}

它應該編譯並引發異常並捕獲。 否則,您的代碼將根本無法編譯。

因為該代碼甚至無法編譯,所以不會引發任何異常。

無論如何-有幾點:

  • 使用異常處理時,將較具體的異常放在較不具體的異常之前(因此, InvalidOperationException的捕獲應在Exception的捕獲之前)。
  • 捕獲Exception通常不是很有用。
  • 如果發現異常,請采取措施。

您可能的意思是:

throw new InvalidOperationException();

但是,按照構造異常的方式, catch(Exception x)塊會運行。

您應該寫:

class xxx
{
    public void Test()
    {
        try
        {
          throw new InvalidoperationException(); 
        }
        catch(InvalidoperationException exception)
        {
            // Do smth with exception;
        }            
        catch(Exception exception)
        {
            throw; // Rethrows your exception;
        }
    } 
}

InvalidOperationException繼承自Exception catch嘗試處理最特定的分支,因此將在此處執行catch (InvalidOperationException x)

不。 它不會編譯。 因此,毫無疑問將生成哪個異常。

您的代碼應如下所示:

class xxx
{
    public void Test()
    {
        try
        {
          throw new InvalidoperationException(); 
        }
        catch(InvalidoperationException exception)
        {
            // Something about InvalidOperationException;
        }            
        catch(Exception exception)
        {
            // Something about the Exception
        }
    } 
}

注意點:

  1. 首先編寫更具體的Exception類,因此我們在Exception類之前編寫InvalidOperationException。

忽略編譯問題...。第一個匹配的異常塊( catch(Exception x) )將獲取異常。 然后,您將忽略異常並且不重新拋出異常,因此外部世界將看到該異常。 但是,這並沒有使其成為一種好的做法……特別是,捕獲一個任意的Exception並忽略它是有風險的-可能是任何事情 ……不一定是您認為的異常。

好的,代碼不會編譯,但是我將忽略它……

如果我看一下這行:

throw new Exception(InvalidoperationException);

首先,根據MSDN,沒有這樣的構造函數。 因此,我假設您的意思是構造函數:Exception(String msg,Exception innerException)。 含義:拋出新的Exception(“ blabla”,InvalidoperationException);

引發的異常類型為Exception,而不是InvalidOperationException 因此, 只有 catch(Exception x)可以捕獲它。

如果你會一直拋出InvalidOperationException異常比你寫的捕撈秩序的方式,異常類會被抓住了。 漁獲物的順序確實很重要。

我能給您的最佳建議就是您自己嘗試一下 ,看看會發生什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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