2

Exception 是一个方便的容器,很容易用于各种目的。但是可以用它来处理代码中的合法状态吗?

我的例子:我有一个几何函数,可以在搜索半径内找到最近的对象:

public IPoint FindNearest(IPoint origin, double searchRadius)
{

}

我的想法是,当搜索没有找到命中时,我可以抛出异常。但这是个好主意吗?或者,我可以返回Null(我不喜欢),或者返回一个结果对象而不是一个点。

4

4 回答 4

5

异常通常表示无效或“异常”场景。在您的情况下,如果没有找到命中是一种特殊情况,并且在通常情况下应该始终找到它,那么您可以抛出异常。

由于其沉重的性质,您应该始终尽量避免抛出异常。如果调用者代码频繁调用此方法,而您的方法导致抛出大量异常,这会使您的程序变慢

于 2012-12-11T10:04:31.413 回答
3

最佳实践是仅当您无法以功能方式处理错误时才使用异常。在这种情况下,最好不要找到位置并返回 null,因为您的调用函数可以以函数方式处理 null。除了干净的代码之外,抛出和处理异常对性能非常不利,因此只能将它们用作最后​​的手段。

于 2012-12-11T10:04:50.183 回答
3

你可以做类似的事情

public bool TryFindNearest(IPoint origin, double searchRadius, out IPoint result)
{
    // your logic here, return true if you find a point. Otherwise return false.
}

然后您的调用代码可以执行以下操作:

IPoint nearestPoint;
If (TryFindNearest(origin, searchRadius, out nearestPoint))
{
    // do your stuff.
}

在不控制程序流程的无效场景中应使用异常。

于 2012-12-11T10:07:32.383 回答
2

通常在这种情况下抛出异常并不是一个好主意,它们很昂贵并且在语义上完全意味着其他东西。

您可以返回 null 并进行 null 检查,或者我偶尔会发现使用Special Case模式效果很好,并且如果您给类/接口一个合理的名称,则可以使代码可读。

在这种情况下,您将返回一个实现类或派生接口,例如:

public class NoHitOnRadius : IPoint {}

并在没有命中时从通话中返回。然后调用代码检查返回类型:

var p = FindNearest(...);

if (p is NoHitOnRadius) 
{
    // Do something.
}

尽管在这种特定情况下,我可能会使用RobH 建议TryFindNearest的语义(以保持与TryParse等的共性)。

于 2012-12-11T10:08:16.037 回答