如何在C#中优雅地测试溢出情况?

时间:2009-02-05 22:04:25

标签: c# exception math exception-handling

更新:我将保留原样:异常的性能损失(非常罕见)优于检查每个操作的可能性能(常见)


我正在尝试支持“EstimatedRowCount”,在一种情况下,它将是两个连接在一起的子游标的产物:

estimatedRowCount = left.EstimatedRowCount * right.EstimatedRowCount;
return estimatedRowCount;

当然,如果左右足够大,这将抛出OverflowException。

在这里,我并不关心estimatedRowCount是否100%准确,只是知道这个光标持有大量数据。

现在,我正在这样做:

// We multiply our rowcount
Int64 estimRowCount = 0;
try
{
    estimRowCount = leftRowCount * rightRowCount;
}
catch (OverflowException)
{
    // Ignore overflow exceptions
    estimRowCount = Int64.MaxValue;
}

return estimRowCount;

有没有更好的方法来测试溢出操作,所以我不必执行try {} catch来保护?

3 个答案:

答案 0 :(得分:4)


if (Int64.MaxValue / leftRowCount <= rightRowCount)
{
    estimRowCount = leftRowCount * rightRowCount
}
else
{
    estimRowCount = Int64.MaxValue;
}

不确定我是否可以在没有编辑的情况下解释自己。 但是,我希望你明白这个想法。

答案 1 :(得分:4)

这听起来像是'unchecked' keyword的一个很好的用例。

要使用,只需将作业包装在“未选中”的块中:

Int64 estimRowCount = 0;
unchecked
{
    estimRowCount = leftRowCount * rightRowCount;
}

然后测试结果是否为负 - 如果是,则溢出:

if (estimRowCount > 0) estimRowCount = Int64.MaxValue;

在这种情况下,您需要确保leftRowCount和rightRowCount都不是负数,但考虑到上下文,我认为不会发生。

答案 2 :(得分:3)

您的解决方案似乎很合理。您想要优化哪些特定的东西?该产品是否经常导致溢出情况,以至于您担心异常处理的性能损失?

(只是简单的思考,如果leftRowCount和rightRowCount是Int32,而不是Int64,那么你的产品不会溢出你的Int64 estimRowCount左值。)