正确重抛例外 (Exception) 的方式
前言
最近在Review项目程序时,发现有把Try-Catch捕捉到之Exception直接抛出的状况(如左下图所示),其实这样是不恰当的做法;较好的方式是使用throw重抛例外就好了(如右下图所示)。这两者到底由何差异,以下将就简单实例来进行探讨。
??
差异比较
大家都知道在捕捉到例外时,可以从Exception.StackTrace属性中来获得调用栈资讯,进而了解错误发生的确切位置,以方便调试作业的进行。以下将就该资讯的完整度探讨两者之差异。
首先,先建立一个调用的推叠类做测试。当调用Aoo.DoSomethingInBoo()方法时,会依序向Boo, Coo, Doo的DoSomethingInXoo()方法执行,且最后在Doo.DoSomethingInDoo()中故意造成错误,再交由Boo.DoSomethingInBoo()捕捉此例外错误,并以 throw ex 或 throw 二次抛出例外至调用端中来比较差异。
调用端测试主程序如下,捕捉到例外错误后印出StackTrace资讯于画面上
throw ex
首先使用throw ex来抛出例外,执行看看
当我们使用 throw ex 时,会重置调用栈,造成确切例外发生位置的遗失。如下图所示,错误发生点明明就在Doo.DoSomethingInDoo()中,而StackTrace提供的数据却只有到Boo.DoSomethingInBoo(),因此单就此消息无法得知实际错误到底是在哪个类方法中发生的,实在是会造成很大的困扰。
throw
接着使用throw来抛出例外,执行看看
使用throw抛出错误时,并不会重置调用栈,保有完整StackTrace资讯,方便获得例外发生点来进行调试。如下图所示,明确地指出错误发生点就在Doo.DoSomethingInDoo()中,获得完整调用栈资讯。
以下是完整的测试代码,有兴趣的朋友可以自行测试
namespace RethrowExceptionConsole
{
class Program
{
static void Main(string[] args)
{
try
{
Aoo aoo = new Aoo();
aoo.DoSomethingInAoo();
}
catch (Exception ex)
{
// display stack trace info
Console.WriteLine( "----- stack info -----" );
Console.WriteLine( ex.StackTrace.ToString() );
Console.WriteLine( "----------------------" );
}
Console.Read();
}
}
// level 1
public class Aoo
{
public Boo boo = new Boo();
public void DoSomethingInAoo()
{ boo.DoSomethingInBoo(); }
}
// level 2
public class Boo
{
public Coo coo = new Coo();
public void DoSomethingInBoo()
{
try
{
coo.DoSomethingInCoo();
}
catch (Exception ex)
{
// log here
// ...
// ## Rethrow exception ##
// destroys the strack trace info!
//throw ex;
// ## Rethrow exception ##
// preserves the stack trace
throw;
}
}
}
// level 3
public class Coo
{
public Doo doo = new Doo();
public void DoSomethingInCoo()
{ doo.DoSomethingInDoo(); }
}
// level 4
public class Doo
{
public void DoSomethingInDoo()
{
int i = 0;
i = 1 / i; // cause exception
}
}
}
希望此篇文章可以帮助到需要的人
若内容有误或有其他建议请不吝留言给笔者喔 !
原文:大专栏 [Tips][C#] 正确重抛例外 (Exception) 的方式
原文地址:https://www.cnblogs.com/chinatrump/p/11518129.html