C# 如何分解try/catch代码?
我有一个C代码,它使用一个可以抛出异常的外部库。 在代码的三个部分中,我希望以以下方式处理这些异常:C# 如何分解try/catch代码?,c#,C#,我有一个C代码,它使用一个可以抛出异常的外部库。 在代码的三个部分中,我希望以以下方式处理这些异常: try { CallOtherLibrary(); } catch(ExceptionA) { ProcessErrorA(); } catch(ExceptionB) { ProcessErrorB(); } 现在我认为复制粘贴这个代码是一种代码气味。 一种可能的修复方法是创建一个将操作作为参数的方法,并执行try/catch。但它迫使我复制调用try/catch的每个方法
try {
CallOtherLibrary();
}
catch(ExceptionA) {
ProcessErrorA();
} catch(ExceptionB) {
ProcessErrorB();
}
现在我认为复制粘贴这个代码是一种代码气味。
一种可能的修复方法是创建一个将操作作为参数的方法,并执行try/catch。但它迫使我复制调用try/catch的每个方法,这会导致更多代码,可读性降低
考虑到我无法更改外部库的行为,处理此问题的干净方法是什么?您可以创建一个Dictionary 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.
}
}
}
您可以创建一个字典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.
}
}
}
您正在寻找外星人库的包装。在C中,这通常是通过使用一个接口和一个充当/的方法来完成的 您创建了一个充当适配器的新类,实现了适配器接口,在实现的方法中,您将获得问题中提到的代码。然后用对新创建的适配器的方法的调用替换原始代码,并在代码库中使用该方法
为您不拥有的库安装适配器并使用此适配器的好处是,如果所述外部库的方法签名将来发生更改,则不必重写您自己的逻辑,而只需在适配层中更改它,您就可以重新设置了。您正在寻找外来库的包装器。在C中,这通常是通过使用一个接口和一个充当/的方法来完成的 您创建了一个充当适配器的新类,实现了适配器接口,在实现的方法中,您将获得问题中提到的代码。然后用对新创建的适配器的方法的调用替换原始代码,并在代码库中使用该方法
为您不拥有的库安装适配器并使用此适配器的好处是,如果所述外部库的方法签名将来发生更改,则不必重写您自己的逻辑,而只需在自适应层中更改它,您就可以重新设置了。也许您可以做类似这样的事情,以适应自己的使用:
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
也许你可以做一些像这样的事情来适应自己的使用:
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
提供一个公共异常处理函数
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();
}
}
提供一个公共异常处理函数
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();
}
}
您是否要执行完全相同的代码来响应完全相同的异常,只是它发生在对另一个库的不同调用期间?我的意思是,ExceptionA在所有情况下都有相同的响应吗?全局异常处理程序可能会有所帮助,如果它适合您的上下文,那么异常处理与日志记录等类似。您是否要执行完全相同的代码来响应完全相同的异常,只是它发生在对另一个库的不同调用期间?我的意思是,ExceptionA在所有情况下都有相同的响应吗?全局异常处理程序可能会有所帮助,如果它适合您的上下文,那么异常处理与日志记录等类似。