2015-02-08 99 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来获取所有堆栈帧。

相关问题