【发布时间】:2014-06-16 18:03:29
【问题描述】:
当抛出异常时,保留堆栈跟踪是最常见的期望行为,在 Java 中这可以通过 throw ex; 获得,但在 C# 中必须使用 throw;。 (还请注意,许多 C# 程序员经常会错误地使用 throw ex; 而不是 throw;)。
如果有时必须清除堆栈跟踪(这种情况不太常见),则可以只抛出一个新异常,例如 throw new MyException(ex.Message, otherDetails);。
那么,考虑到上述情况,在 C# 中使用单独的 throw; 语句有什么好处?
或者,换句话说:为什么 C# 使用一个特殊的单独语句 (throw;),这是鲜为人知的,用于最常用的情况(当用户想要保留堆栈跟踪时),它使用更自然的throw ex; 对于不太常见的情况(清除堆栈跟踪时)?还有其他我没有介绍的可能用例吗?
C# 和 Java 中的代码示例:
// This is the C# design
try
{
//...
}
catch (MyException ex)
{
// rethrow so that stack trace is preserved
ex.AppendData(contextVariable);
throw;
}
catch (PrivateException ex)
{
// throw new exception so stack trace is not preserved
throw new PublicException(ex.Message);
}
// This is the Java design
try
{
//...
}
catch (MyException ex)
{
// rethrow so that stack trace is preserved
ex.AppendData(contextVariable);
throw ex;
// and I can even choose to use something like, where ProcessException(ex) will return the same ex
throw ProcessException(ex, contextVariable);
}
catch (PrivateException ex)
{
// throw new so stack trace is not preserved
throw new PublicException(ex.getMessage());
}
【问题讨论】:
-
询问自 C# 版本 1 以来一直存在的语言设计功能似乎很奇怪。
-
@JohnSaunders 虽然该功能是 C# 版本 1 的形式,但我仍然不明白其背后的原因。
-
请查看stackoverflow.com/questions/730250/…(我相信这完全涵盖了您的问题的一部分,不是基于非观点或历史研究的部分)。随时提出新问题,明确说明您在理解该行为时遇到的问题。
-
对于历史研究,请确保在blogs.msdn.com 上找到并阅读相应的博客并将发现添加到问题中。请注意,历史研究问题通常过于宽泛,因此请务必说明您需要留下的充分理由。
-
@AlexeiLevenkov 这个问题不是重复的。另一个问题问有什么区别,但我问为什么需要两种不同的陈述。如果这是基于意见的,我应该在哪里问?我仍然在 stackoverflow 上找到许多其他基于意见的问题,这些问题尚未结束,我认为基于意见的答案对于更好地理解不同主题很有价值。
标签: c# syntax exception-handling