我在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"));
}
}
方法3它将被不同的方法调用,它返回Method3Exception,我需要重新抛出从Method2到Method1的异常,但我不希望在Method1上捕获Method3Exception。最好的方法是什么?
任何建议
答案 0 :(得分:4)
术语(重新)抛出通常是指将异常抛回到调用者,保留堆栈跟踪(包含完全发生异常的位置)。这可以使用throw;
完成,而不指定与throw ex
相反的异常操作数:
try
{
Method3();
}
catch(Method3Exception)
{
throw;
}
然而,如果您只想在该方法中添加之前没有任何内容。它没用,只需删除try..catch,异常就会传播给调用者,这是默认行为。
Docs:
可以在catch块中使用throw语句来重新抛出 捕获块被捕获的异常。在这种情况下,投掷 语句不带异常操作数。
答案 1 :(得分:3)
重新抛出异常的替代方法(使用其他答案中描述的throw;
)是将异常包装在内部异常中。如MSDN中所述,所有自定义异常应至少有四个构造函数,其中一个是
public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }
因此,如果所有自定义异常都是这样的,您可以将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
中的内部异常,可以使用属性InnerException
:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
if(ex.InnerException != null)
{
var message = ex.InnerException.Message;
// Do what you need with the message
}
}
}
答案 2 :(得分:0)
在Method2
中,您可以使用现有Method2Exception
作为Method3Exception
投放新的InnerException
:
try
{
Method3();
}
catch(Method3Exception method3Exception)
{
throw new Method2Exception("Message", method3Exception);
}
然后你可以抓住上面的Method2Exception
:
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
答案 3 :(得分:0)
默认情况下,异常会冒泡。例如,
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 上记录例外,但仍希望在 FourthMethod 处理你的例外,那么你必须选择:< / p>
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
}
}