在finally块中获取抛出异常

TcK*_*cKs 6 c# exception-handling finally

有没有办法,如何获得当前抛出的异常(如果存在)?

我想减少代码量并对任务应用一些重用,如下所示:

Exception thrownException = null;
try {
    // some code with 3rd party classes, which can throw unexpected exceptions
}
catch( Exception exc ) {
    thrownException = exc;
    LogException( exc );
}
finally {
    if ( null == thrownException ) {
        // some code
    }
    else {
        // some code
    }
}
Run Code Online (Sandbox Code Playgroud)

并用以下代码替换它:

using( ExceptionHelper.LogException() ) {
    // some code with 3rd party classes, which can throw unexpected exceptions
}
using( new ExceptionHelper { ExceptionAction = ()=> /*some cleaning code*/ } ) {
    // some code with 3rd party classes, which can throw unexpected exceptions
}

public class ExceptiohHelper : IDisposable {
    public static ExceptionHelper LogException() {
        return new ExceptionHelper();
    }

    public Action SuccessfulAction {get; set;}
    public Action ExceptionAction {get; set;}

    public void Dispose() {
        Action action;
        Exception thrownException = TheMethodIDontKnow();
        if ( null != thrownException ) {
            LogException( thrownException );
            action = this.ExceptionAction;
        }
        else {
            action = this.SuccessfulAction;
        }

        if ( null != action ) {
            action();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这种情况是否可行?

谢谢

Mar*_*ann 8

想法是你在catch块中处理异常......

也就是说,Exception是一个引用类型,所以你总是可以在try范围之外声明一个Exception变量...

Exception dontDoThis;
try
{
    foo.DoSomething();
}
catch(Exception e)
{
    dontDoThis = e;
}
finally
{
    // use dontDoThis...
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,我知道 try-catch-finally 的方式。我现在使用它,正如我在问题中所说的 - 请再读一遍。但我想减少编写代码,并扩展重用能力。这不是任何方式的答案:( (3认同)

Kim*_*jor 5

您对以下内容有何看法。与其将问题视为“如何获得最后一个异常?”,不如将其更改为“如何运行具有更多控制权的代码?”

例如:您可以使用 ActionRunner 代替 ExceptionHelper。

public class ActionRunner
{
    public Action AttemptAction { get; set; }
    public Action SuccessfulAction { get; set; }
    public Action ExceptionAction { get; set; }

    public void RunAction()
    {
        try
        {
            AttemptAction();
            SuccessfulAction();
        }
        catch (Exception ex)
        {
            LogException(ex);
            ExceptionAction();
        }
    }

    private void LogException(Exception thrownException) { /* log here... */ }
}
Run Code Online (Sandbox Code Playgroud)

假设只有 AttemptAction 在调用之间有所不同,它至少会给你一些SuccessfulAction 和ExceptionAction 的重用。

var actionRunner = new ActionRunner
{
    AttemptAction = () =>
    {
        Console.WriteLine("Going to throw...");
        throw new Exception("Just throwing");
    },
    ExceptionAction = () => Console.WriteLine("ExceptionAction"),
    SuccessfulAction = () => Console.WriteLine("SuccessfulAction"),
};
actionRunner.RunAction();

actionRunner.AttemptAction = () => Console.WriteLine("Running some other code...");
actionRunner.RunAction();
Run Code Online (Sandbox Code Playgroud)