2015-02-08 112 views
13

我想超載throw關鍵字來捕獲繼承自Exception的類,並讓它在實際拋出之前執行一些日誌記錄和其他內容。這可能嗎?或者我必須使用常規功能?我可以重載throw關鍵字嗎?

我已經試過:

public class cSilException : Exception 
    { 
     private string m_strMsg; 

     public override void throw(cSilException ex) 
     { 

     } 
... 
... 
} 
+6

它有什麼用處? – 2015-02-08 13:15:06

+2

關鍵字不可覆蓋也不可重載。 – 2015-02-08 14:59:46

+0

另外,如果你可以重寫拋出,你可以看到底層庫的一些意想不到的結果。 :) – eandersson 2015-02-09 00:25:25

回答

21

你想要做的就是添加一個構造函數的例外,做任何你需要的是構造函數內完成。

public class cSilException : Exception 
{ 
    //constructor 
    public cSilException() 
    { 
     // do stuff here 
    } 
} 

你「超負荷throw關鍵字」的概念是非常,呃,如何把它,迷幻

當然,正如很多人指出的那樣,如果您的意圖是做日誌等事情,最好避免這樣做。 Alois Kraus已經發布了另一個有很好建議的答案。

+9

請注意,如果您在ctor中記錄異常,則很可能會看到從未實際拋出的記錄異常 - 僅實例化。爲了記錄目的,最好有一個擴展/輔助方法'LogAndThrow'。 – SimpleVar 2015-02-08 13:39:22

+2

另外,異常可能會被捕獲並重新生成 - 在這種情況下,您只會看到一條日誌消息。 – 2015-02-08 13:50:13

+1

而且這也適用於C++。完全相同的方式。 – 2015-02-09 00:10:32

2

你不能重載throw它是語言(不是類的成員)的一個組成部分

如果你想處理一個特定的異常,你應該catch是例外:

try 
{ 
    // your code, which throws some exceptions 
} 
catch(cSilException csEx) 
{ 
    // handle csEx 
    throw; // rethrow this exception 
} 
catch(Exception ex) 
{ 
    // handle all other exceptions 
} 

該代碼捕獲特殊異常cSilException與其他所有異常不同的代碼塊。

2

尋找方法和Exception類的成員。您可以定義構造函數cSilException這樣

public cSilException(string message) 
{ 
    Message = message; 
} 

,比catch (cSilException ex)Console.WriteLine(ex.Message);

7

我不會推薦記錄異常的構造函數裏的任何東西,因爲它違反了單一職責原則,被認爲是不好的設計。此外,創建異常並不一定意味着它已被拋出,而且異常可能被捕獲並重新生成 - 這些事情可能會導致不正確的日誌消息。

而是,您可以使用應用程序範圍的異常處理程序,它將根據您的預定義策略來處理異常。例如,您可以查看Enterprise Library Exception Handling Block,特別是this section

23

註冊事件AppDomain.FirstChanceException.在實際拋出之前,您會看到所有異常。在事件處理程序中,您可以檢查您的exception並執行所需的日誌記錄。

沒有魔力和沒有壞設計。

class Program 
{ 
    static void Main(string[] args) 
    { 
     AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException; 
     DoBadThings(); 
    } 

    private static void DoBadThings() 
    { 
     DoOneLevelBelow(); 
    } 

    private static void DoOneLevelBelow() 
    { 

     for(int i=0;i<10;i++) 
     { 
      try 
      { 
       if (i == 5) 
       { 
        var invalidCast = (string)((object)i); 
       } 
       else 
       { 
        throw new InvalidTimeZoneException(); 
       } 
      } 
      catch 
      { 

      } 
     } 
    } 

    static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e) 
    { 
     if(e.Exception is InvalidCastException) 
     { 
      LogInvalidCast((InvalidCastException)e.Exception); 
     } 
    } 

    private static void LogInvalidCast(InvalidCastException invalidCastException) 
    { 
     Console.WriteLine("Got Invalid cast: {0}", invalidCastException); 
    } 

這將導致:

得到無效的轉換:System.InvalidCastException:類型 "System.Int32"不能轉換到 「System.String」 的對象。在 ThrowTest.Program.DoOneLevelBelow()在 d:\媒體\博客\ ThrowTest \的Program.cs:行31

請注意,因爲你得到異常的堆棧展開之前,你會看到只有方法在那裏確實發生了但沒有調用方法,因爲堆棧還沒有被解開。 如果您想要完整的調用堆棧,則可以使用Environment.StackTrace來獲取所有堆棧幀。

相關問題