[英]Proper way to rethrow an exception
我在c#中具有以下方法:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
}
void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}
//Do something and call method3
try
{
Method3();
}
catch(Method3Exception)
{
//??
}
}
void Method3()
{
//Do something
if(error)
{
throw(new Method3Exception("error"));
}
}
Method3将由不同的方法调用,并且它返回Method3Exception,我需要将异常从Method2抛出到Method1,但是我不想在Method1上捕获Method3Exception。 最好的方法是什么?
有什么建议么
术语(重新)抛出通常是指将异常返回给调用方,以保留堆栈跟踪(其中包含异常发生的确切位置)。 可以使用throw;
来完成throw;
没有指定与throw ex
相反的异常操作数:
try
{
Method3();
}
catch(Method3Exception)
{
throw;
}
但是 ,如果您只想在该方法中添加一个之前没有任何内容的throw。 这是没有用的,只需删除try..catch,异常将传播到调用方,这是默认行为。
文件 :
在catch块中可以使用throw语句重新抛出catch块捕获的异常。 在这种情况下,throw语句不采用异常操作数。
重新抛出异常的另一种方法(使用throw;
如其他答案所述)是将异常包装在内部异常中。 如MSDN中所述 ,所有自定义异常都应至少具有四个构造函数,其中之一是
public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }
因此,如果您所有的自定义异常都是这样,则可以将Method3
的异常Method3
为内部异常:
void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}
//Do something and call method3
try
{
Method3();
}
catch(Method3Exception exc)
{
throw new Method2Exception("error", exc); // exc is passed as inner exception
}
}
然后,如果要检查Method1
的内部异常, Method1
可以使用属性InnerException
:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
if(ex.InnerException != null)
{
var message = ex.InnerException.Message;
// Do what you need with the message
}
}
}
在Method2
,可以引发一个新的Method2Exception
,并将现有的Method3Exception
作为其InnerException
:
try
{
Method3();
}
catch(Method3Exception method3Exception)
{
throw new Method2Exception("Message", method3Exception);
}
然后,您可以捕获上面的Method2Exception
:
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
默认情况下例外是气泡。 例如,
void FirstMethod()
{
int a = 0;
int b = 10;
int c = b / a;
}
void SecondMethod()
{
FirstMethod();
}
void ThirdMethod()
{
SecondMethod();
}
void FourthMethod()
{
try
{
ThirdMethod();
}
catch (DivideByZeroException ex)
{
// Handle error
}
}
异常将在FirstMethod中发生,并且会上升,并将在ForurthMethod中进行处理 。 例如,如果要在ThirdMethod中 记录异常,但仍希望在ThirdMethod中处理异常,则必须选择:
void ThirdMethod()
{
try
{
SecondMethod();
}
catch (Exception ex)
{
// Log the error
throw; // Throw exception without affecting StackTrace
}
}
在C#6.0之后,您可以通过使用异常过滤器轻松地做到这一点。 创建一个返回false的记录器方法。
bool Log(Exception ex)
{
// Log the error
return false;
}
在第三个方法中添加异常过滤器 :
void ThirdMethod()
{
try
{
SecondMethod();
}
catch (Exception ex) when(Log(ex))
{
// Debugger won't reach here
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.