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

Ser*_*hov 5 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ell 6

这取决于...如果存在那么多共性,你可以传递作为参数事情 - 作为接口或委托:

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

并致电:

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

Foo(delegate { /* logic B */ });
Run Code Online (Sandbox Code Playgroud)


Dan*_*ker 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

例:

int queueSize = Catching<MyParsingException>
    .Try(() => Parse(optionStr, "QueueSize"), 5);
Run Code Online (Sandbox Code Playgroud)

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

这有助于避免分解代码流,还可以集中您的日志记录策略.

您可以为特殊情况编写此类异常包装的特殊版本,例如捕获特定的三个异常集,或者其他任何内容.