我可以重载throw关键字吗?

Ami*_*man 13 c# exception throw

我想重载throw关键字以捕获一个继承自Exception的类,并让它在实际抛出之前执行一些日志记录和其他操作.这可能吗?或者我必须使用常规功能?

我试过了:

public class cSilException : Exception
    {
        private string m_strMsg;

        public override void throw(cSilException ex)
        {

        }
...
...
}
Run Code Online (Sandbox Code Playgroud)

Alo*_*aus 24

注册事件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);
    }
Run Code Online (Sandbox Code Playgroud)

这将导致:

获得了无效的转换:System.InvalidCastException:该类型的对象 "System.Int32"无法转换为"System.String".在 ThrowTest.Program.DoOneLevelBelow()在d:\媒体\博客\ ThrowTest \的Program.cs:行31.

请注意,因为你在解开堆栈之前得到了异常,你将只看到它确实发生的方法而不是调用方法,因为堆栈还没有解开.如果需要完整的调用堆栈,可以使用它Environment.StackTrace来获取所有堆栈帧.


Mik*_*kis 21

你想要做的是在你的异常中添加一个构造函数,并在该构造函数中做你需要做的任何事情.

public class cSilException : Exception
{
    //constructor
    public cSilException()
    {
        // do stuff here
    }
}
Run Code Online (Sandbox Code Playgroud)

你的"重载关键字"这个概念非常呃,如何把它放进去,迷幻.

当然,正如许多人所指出的那样,如果您的目的是做日志记录等事情,最好避免这样做.Alois Kraus发布了另一个非常好的建议.

  • 请注意,如果您在ctor中记录异常,您很可能会看到从未实际抛出的记录异常 - 仅实例化.出于日志记录的目的,最好有一个扩展/辅助方法`LogAndThrow`. (9认同)
  • 此外,异常可能被捕获并重新抛出 - 在这种情况下,您只会看到一条日志消息. (2认同)

Adi*_*ter 8

我不建议在异常的构造函数中记录任何内容,因为它违反了单一责任原则并被认为是一个糟糕的设计.此外,创建异常的事实并不一定意味着它已被抛出,此外,异常可以被捕获和重新抛出 - 这些可能导致不正确的日志消息.

相反,您可以使用应用程序范围的异常处理程序,该处理程序将根据您的预定义策略处理异常.例如,您可以查看企业库异常处理块,特别是本节.