在C#中重用异常处理逻辑的最佳方法是什么?

时间:2009-06-25 22:10:25

标签: c#

我有两个函数具有不同的逻辑但几乎相同的异常处理:

public void DoIt1  // DoIt2 has different logic but same exception handling
{
    try
       ... DoIt1 logic
    catch (MySpecialException myEx)
    {
       Debug.WriteLine(myEx.MyErrorString);
       throw;
    }
    catch (Exception e)
    {
       Debug.WriteLine(e.ToString());
       throw;
    }
}

不可能为DoIt1和DoIt2使用单个入口点,因为它们是从外部调用的。 Copy / Pase(异常块)是最好的方法吗?

5 个答案:

答案 0 :(得分:6)

这取决于...如果有那么多的共性,你可以将做的事情作为参数传递 - 作为接口或委托:< / p>

void Foo(Action thingToDo) {
    if(thingToDo == null) throw new ArgumentNullException("thingToDo");
    try {
        thingToDo();
    } catch {...} // lots of
}

并致电:

Foo(delegate { /* logic A */ });

Foo(delegate { /* logic B */ });

答案 1 :(得分:5)

尝试:

public static class Catching<TException> where TException : Exception
{
    public static bool Try<T>(Func<T> func, out T result)
    {
        try
        {
            result = func();
            return true;
        }
        catch (TException x) 
        {
            // log exception message (with call stacks 
            // and all InnerExceptions)
        }

        result = default(T);
        return false;
    }

    public static T Try<T>(Func<T> func, T defaultValue)
    {
        T result;
        if (Try(func, out result))
            return result;

        return defaultValue;
    }
}

示例:

int queueSize = Catching<MyParsingException>
    .Try(() => Parse(optionStr, "QueueSize"), 5);

如果Parse抛出MyParsingException,则queueSize将默认为5,否则将使用Parse返回的值(或任何其他异常将传播通常,这通常是您想要的意外异常。)

这有助于避免分解代码流,并且还集中了您的日志记录策略。

您可以针对特殊情况编写此类异常包装的专用版本,例如:捕捉一组特定的三个例外或其他。

答案 2 :(得分:2)

对于可能解决方案的极端,请查看面向方面编程技术以及PostSharpMicrosoft Policy Injection Block等工具。通过这种方式,您可以定义一个 aspect ,它可以在异常上执行某些操作,并将编织到您需要它的代码中的所有位置。

答案 3 :(得分:1)

如果您只想记录异常的消息和项目,而不在catch块中进行特殊处理,则可以创建基于反射的对象记录器,并将异常作为参数传递。这样做,你没有很多捕获块。

如果您是代码的所有者,可以将日志记录过程放在MySpecialException的构造函数中,删除catch的块并使代码更清晰。

答案 4 :(得分:0)

你可以拥有类似的东西:

public static class ErrorHandler
{

    public static void HandleMyException(MyException myEx)
    {
        Debug.WriteLine(myEx.MyErrorString);
        throw;
    }

    public static void HandleException(Exception myEx)
    {
        Debug.WriteLine(e.ToString());
        throw;
    }

}

或者,在这种特定情况下,具有更通用的功能,如:

public static class ErrorHandler
{

    public static void WriteAndThrow(string msg)
    {
        Debug.WriteLine(msg);
        throw;
    }

}