我有两个函数具有不同的逻辑但几乎相同的异常处理:
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(异常块)是最好的方法吗?
答案 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)
对于可能解决方案的极端,请查看面向方面编程技术以及PostSharp或Microsoft 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;
}
}