为什么在C#中捕获并重新抛出异常?
我正在查看可串行化DTO上的文章C# - 数据传输对象。
文章包含这段代码:
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
catch(Exception ex) {
throw ex;
}
}
本文的其余部分看起来理智和合理(对于noob),但是try-catch-throw会抛出WtfException ...... 这不完全等同于不处理异常吗?
人机工程学:
public static string SerializeDTO(DTO dto) {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
或者我错过了一些关于C#中错误处理的基础知识? 它几乎与Java相同(减去检查的异常),不是吗? ......也就是说,他们都精炼了C ++。
堆栈溢出问题重新抛出无参数捕获和不做任何事情之间的区别? 似乎支持我的观点,即尝试抛出是无效的。
编辑:
只是为了总结任何未来发现此线程的人...
不要
try {
// Do stuff that might throw an exception
}
catch (Exception e) {
throw e; // This destroys the strack trace information!
}
堆栈跟踪信息对于确定问题的根本原因至关重要!
做
try {
// Do stuff that might throw an exception
}
catch (SqlException e) {
// Log it
if (e.ErrorCode != NO_ROW_ERROR) { // filter out NoDataFound.
// Do special cleanup, like maybe closing the "dirty" database connection.
throw; // This preserves the stack trace
}
}
catch (IOException e) {
// Log it
throw;
}
catch (Exception e) {
// Log it
throw new DAOException("Excrement occurred", e); // wrapped & chained exceptions (just like java).
}
finally {
// Normal clean goes here (like closing open files).
}
在较不具体的例外之前捕捉更具体的例外(就像Java一样)。
参考文献:
第一; 文章中的代码的做法是邪恶的。 throw ex
会将异常中的调用堆栈重置为该throw语句的位置; 失去了关于实际创建异常的信息。
第二,如果你正好赶上并重新抛出这样的,我看不出有任何的附加价值,代码示例上面会一样好(或者,考虑到throw ex
位,甚至更好),而在try-catch。
但是,有些情况下您可能想要捕捉并重新抛出异常。 记录可能是其中之一:
try
{
// code that may throw exceptions
}
catch(Exception ex)
{
// add error logging here
throw;
}
不要这样做,
try
{
...
}
catch(Exception ex)
{
throw ex;
}
你将失去堆栈跟踪信息...
要么,
try { ... }
catch { throw; }
要么
try { ... }
catch (Exception ex)
{
throw new Exception("My Custom Error Message", ex);
}
你可能想要重新抛出的原因之一是,如果你正在处理不同的例外情况,例如
try
{
...
}
catch(SQLException sex)
{
//Do Custom Logging
//Don't throw exception - swallow it here
}
catch(OtherException oex)
{
//Do something else
throw new WrappedException("Other Exception occured");
}
catch
{
System.Diagnostics.Debug.WriteLine("Eeep! an error, not to worry, will be handled higher up the call stack");
throw; //Chuck everything else back up the stack
}
C#(在C#6之前)不支持CIL“过滤的异常”,这是VB所做的,因此在C#1-5中,重新抛出异常的一个原因是您在catch()时没有足够的信息。以确定您是否想要实际发现异常。
例如,在VB中你可以做
Try
..
Catch Ex As MyException When Ex.ErrorCode = 123
..
End Try
......它不会用不同的ErrorCode值处理MyExceptions。 在v6之前的C#中,如果ErrorCode不是123,则必须捕获并重新抛出MyException:
try
{
...
}
catch(MyException ex)
{
if (ex.ErrorCode != 123) throw;
...
}
由于C#6.0可以像使用VB一样进行过滤:
try
{
// Do stuff
}
catch (Exception e) when (e.ErrorCode == 123456) // filter
{
// Handle, other exceptions will be left alone and bubble up
}
链接地址: http://www.djcxy.com/p/14011.html
上一篇: Why catch and rethrow an exception in C#?
下一篇: How do I discover memory usage of my application in Android?