如何分解try / catch代码?

时间:2016-09-28 11:50:14

标签: c#

我有一个C#代码正在使用可以抛出异常的外部库。 在我的代码的三个部分中,我想通过以下方式处理这些异常:

try {
   CallOtherLibrary();
}
catch(ExceptionA) {
   ProcessErrorA();
} catch(ExceptionB) {
   ProcessErrorB();
}

现在我认为粘贴此代码的副本是一种代码味道。 一种可能的方法来修复它以创建一个将操作作为参数的方法,并执行try / catch。但是它迫使我复制每个调用try / catch的方法,这会导致更多的代码,不太可读。

由于我无法更改外部库的行为,处理此问题的干净方法是什么?

4 个答案:

答案 0 :(得分:2)

您可以制作Dictionary<Type, Action> exceptionHandlers,然后致电 在catch区块中exceptionHandlers[exception.GetType()]()

    void ProcessErrorA() { }

    void Main() 
    {
        Dictionary<Type, Action> exceptionHandlers = new Dictionary<Type, Action>();
        exceptionHandlers.Add(typeof(NullReferenceException), ProcessErrorA);

        try{}
        catch (Exception e) 
        {
            if (exceptionHandlers.ContainsKey(e.GetType()))
            {
                exceptionHandlers[e.GetType()]();
            }
            else 
            {
                // We don't have any handler for this exception. 
            }
        }
    }

答案 1 :(得分:2)

您正在寻找外星人图书馆的包装。在C#中,通常使用interface并使用充当Facade / Adapter的方法来完成此操作。

您创建一个充当适配器的新类,实现适配器接口,并且在实现的方法中,您将获得您在问题中提到的代码。然后,通过调用新创建的适配器的方法替换原始代码,并在代码库中使用该代码。

如果所有外部库的方法签名在将来发生变化,那么为你不拥有的库和使用这个适配器提供适配器的好处就不必重写你自己的逻辑,而只是在适应时改变它层,然后你又完成了。

答案 2 :(得分:0)

也许你可以做这样的事情(适合自己使用):

class Program
{
    public int Divide_InExternalLib(int a, int b)
    {
        Console.WriteLine(string.Format("a={0}, b={1}", a, b));
        int result = a / b;
        Console.WriteLine(string.Format("Result = {0}", result));
        return result;
    }


    public void CallExternalFunction(Action funct)
    {
        try
        {
            funct.Invoke();
        }
        catch (Exception ex)
        {
            Console.WriteLine(string.Format("Exception caught: {0}", ex.ToString()));
        }
    }

    static void Main(string[] args)
    {
        var p = new Program();
        int a = 6;
        int b = 2;
        p.CallExternalFunction(() => { p.Divide_InExternalLib(a, b); });
        b = 0;
        p.CallExternalFunction(() => { p.Divide_InExternalLib(a, b); });

        Console.ReadLine();
    }
}

输出

a=6, b=2
Result = 3
a=6, b=0
Exception caught: System.DivideByZeroException: Attempted to divide by zero.
   at GenericExceptionHandling.Program.Divide_InExternalLib(Int32 a, Int32 b) in
 c:\users\siebiers\documents\visual studio 2015\Projects\GenericExceptionHandlin
g\GenericExceptionHandling\Program.cs:line 16
   at GenericExceptionHandling.Program.<>c__DisplayClass2_0.<Main>b__1() in c:\u
sers\siebiers\documents\visual studio 2015\Projects\GenericExceptionHandling\Gen
ericExceptionHandling\Program.cs:line 41
   at GenericExceptionHandling.Program.CallExternalFunction(Action funct) in c:\
users\siebiers\documents\visual studio 2015\Projects\GenericExceptionHandling\Ge
nericExceptionHandling\Program.cs:line 26

答案 3 :(得分:0)

提供常见的异常处理函数

static void Main(string[] args)
        {
            try
            {
                CallOtherLibrary();
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }


        private static void HandleException(Exception ex)
        {
            if (ex is ExceptionA)
            {
                ProcessErrorA();
            }
            else if (ex is ExceptionB)
            {
                ProcessErrorB();
            }
        }
相关问题