我可以重载throw关键字吗?

时间:2015-02-08 13:11:29

标签: c# exception throw

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

我试过了:

public class cSilException : Exception
    {
        private string m_strMsg;

        public override void throw(cSilException ex)
        {

        }
...
...
}

5 个答案:

答案 0 :(得分: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);
    }

这将导致:

  

获得无效演员:System.InvalidCastException:该类型的对象   "System.Int32"无法转换为“System.String”。在   ThrowTest.Program.DoOneLevelBelow() in   d:\ Media \ Blog \ ThrowTest \ Program.cs:第31行。

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

答案 1 :(得分:21)

您要做的是在您的异常中添加一个构造函数,并在该构造函数中执行您需要执行的任何操作。

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

你的概念&#34;重载了throw关键字&#34;非常,呃,怎么说,迷幻

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

答案 2 :(得分:8)

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

相反,您可以使用应用程序范围的异常处理程序,该处理程序将根据您的预定义策略处理异常。例如,您可以查看Enterprise Library Exception Handling Block,特别是this section

答案 3 :(得分: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

答案 4 :(得分:2)

查找Exception类的方法和成员。您可以像{/ p>这样定义cSilException的构造函数

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

而不是catch (cSilException ex)Console.WriteLine(ex.Message);