假设我们有一个方法处理树状分层数据结构中的操作,该数据结构位于处理此类结构的类中。
让我们仔细看看其中一种方法:
void MoveNode(Node currentNode, Node newParentNode)
{
/* check if new parent isn't current's child already */
if (newParentNode.LMargin < currentNode.LMargin && newParentNode.RMargin > currentNode.RMargin)
{
//DO WORK
}
else throw new ArgumentException("New parent node cannot be current's own child");
}
MSDN 声明:不要抛出异常来控制流程!
我的问题:您认为这种 ArgumentException 的使用是否合适,或者您会使用某种返回值。 如果是这样,您将如何提供错误/验证消息。
最佳答案
由于抛出的异常表明此处存在错误,因此在正常工作的程序中永远不会抛出异常,因此异常是正确的选择。
你不应该做的是:
try
{
MoveNode(...)
//Do something
}
catch(ArgumentException e)
{
//Do something else
}
在该示例中,您希望定期抛出异常并使用它来控制控制流。在调用者中捕获 ArgumentException
几乎总是一个坏主意。这种异常应该只在顶级处理程序中捕获,如果有的话。
我个人不喜欢在 else 子句中抛出异常。我更喜欢在函数开始时进行参数检查,然后立即抛出异常。这可以防止在多个 if block 中嵌套非错误代码。
异常分为三种
- 异步异常,如 StackOverflow、OutOfMemory 和 ThreadAborted。它们可能发生在任何地方,而且无法真正处理
- 错误异常,如 ArgumentException,将它们记录在顶级处理程序中并修复错误
- 预期的异常指示可以在本地处理的错误。通常,当错误不常见并且您无法事先知道某个操作会导致错误时,您会使用这些。 IO错误就是一个典型的例子。
原因通常是外部的。例如无法访问的文件、网络故障或您尝试解析的文件中的无效数据。
Eric Lippert 在博客条目中讨论了这些类型的异常:Vexing exceptions
什么时候用第三种异常,什么时候用返回值是判断调用。
关于c# - .NET 返回值与抛出的异常设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4884539/