2017-06-02 84 views
0
try {...} 
catch (InvalidDataException ex){...} 

可以捕獲在try塊中引發的InvalidDataException類的任何實例。如何捕獲特定異常實例而不是特定異常類的任何實例?

try塊有可能包含幾個可以引發InvalidDataException類實例的地方時,是否可以捕獲特定實例?

謝謝。

+0

有幾種方法可以做到這一點 - 多個嘗試塊,拋出不同的異常類型,過濾消息 - 但這對我來說似乎是一個XY問題。你能否提供一個更完整的例子來說明你想要做的事情? –

+0

通用異常與自定義異常類?如果它的泛型沒有辦法區分哪個實例,唯一的方法是創建自定義的Exception類,該類從具有特定標誌或枚舉的'InvalidDataException'繼承,當發生異常時,將該InvalidDataException與所述枚舉。 – t0mm13b

+0

@BJ:我期待一些方法來拋出一個異常,在一個測試方法的單元測試方法。所以我在'try'塊中調用了其他方法,並且需要捕獲該方法可能引發的任何異常。但是我不能排除是否可以從'try'塊中的其他代碼行拋出同一類的另一個異常,所以我需要區分拋出哪個異常實例,並且只捕獲正在測試的方法拋出的異常。 – Tim

回答

1

基本上你可以做類似

try {...} 
catch (InvalidDataException ex) 
{ 
    if (ex == myInstance) { 
     // do something 
    } else { 
     throw; 
    } 
} 

但我會強烈建議反對。您不應該使用異常來控制程序流。

+0

這不需要'myInstance'是一個在'try'塊之外聲明的異常,甚至在它被提升之前嗎?這似乎很奇怪。 –

+0

@BJMyers是的,這就是爲什麼整個想法很糟糕。 – Adrian

0

您可以通過使用堆棧跟蹤識別它:

var stackTrace = new StackTrace(exception, true); 

然後,你可以調用幀(或幀的陣列),並使用其屬性:

var methodThatCalled = stackTrace.GetFrames()[0].GetMethod().Name; 
1

如果我理解正確的話 - 你有一個try塊。在try區塊內有幾個類似的操作可能會導致InvalidDataException。你想抓住一些但不抓住別人。

正如所暗示的,這可能是一個XY問題,但這裏是如何從字面上做你在C#7中所說的話。我不推薦這個,只是從字面上回答這個問題。

bool catching = false; 
try 
{ 
    catching = true; 
    // now exceptions are caught in the catch block. 

    catching = false 
    // now exceptions aren't caught - they are thrown to the calling method. 

} 
catch (InvalidDataException ex) when (catching) 
{ 

} 
1

這是一個簡單的例子

[Serializable] 
    public class MyException : Exception 
    { 
     public MyException() { } 
     public MyException(string message) : base(message) { } 
     public MyException(string message, Exception inner) : base(message, inner) { } 

     protected MyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } 
    } 

    class Program { 
     static void Main(string[] args) { 
      try{ 
       throw new MyException("Whoops#1"); 
       //throw new MyException("Fubar#2"); 
      }catch(MyException myEx){ 
       string aExMsg = myEx.Message; 
       if (aExMsg.Contains("#1")){ 
        Console.WriteLine("Whoops was caught"); 
       } 
       if (aExMsg.Contains("#2")){ 
        Console.WriteLine("Fubar was caught"); 
       } 
      }catch (Exception ex){ 
       throw; 
      } 
      Console.Write("Press <ENTER> to continue..."); 
      Console.ReadLine(); 
     } 
    } 

取消對線//throw new MyException("Fubar#2");並運行它,該catchMyException意願捕獲錯誤,檢查Message類的內容,尋找一個特定線索,從而可以得到一個實例。

但是,必須指出的是,這並不是處理異常,或者通過這樣做來控制代碼流的好方法。確定它是什麼樣的時候,不關心甚至走下坡路 - 爲什麼?在那裏花費的時間太多了!只要看看Message部分的線索就可以了。

例外情況,是出於某種原因,當出現錯誤情況時,兩個結果 - 抓住它們或者悄悄丟棄(壞!)。

查看上面的示例代碼,如果這是某種形狀或形式的處理數據的一部分,它會影響即將執行的依賴類或方法嗎?

爲了即將執行的依賴類或方法的好處,以這種方式設置了一對行程開關標誌,以使得當進一步的代碼被執行時;它會看到之前設置的行程開關標誌,跳過一堆代碼,知道之前發生了錯誤,會使事情變得更糟。

最後,優雅地記錄下來,通知運營商只需在運營商看到的某個彈出窗口或組件中使用ERROR這個詞,它就會給他們一個不需要的恐慌和壓力。