C#如何安全地将十进制数转换为整数

11
我想安全地将一个十进制数转换为整数。
类似于:
public static bool Decimal.TryConvertToInt32(decimal val, out int val)

如果无法转换为整数,则返回false;如果可以成功输出,则返回true。

这是为了避免在decimal.ToInt32方法中捕获OverflowException。最简单的方法是什么?


1
只有两种情况会抛出OverflowException,即x < int.MinValue和x > int.MaxValue,难道你不能只使用一个“if”语句吗? - harold
4
如果给它0.5,你希望它做什么? - Jon Skeet
1
你想四舍五入还是直接截断小数? - AllenG
我想要截断,就像整数转换目前所做的那样。我知道我可以检查 int.min 和 int.max,但是我试图避免额外的检查,因为转换函数也会进行这些检查。 - Superman
5个回答

11

这里:

public static bool TryConvertToInt32(decimal val, out int intval)
{
    if (val > int.MaxValue || val < int.MinValue)
    {
      intval = 0; // assignment required for out parameter
      return false;
    }

    intval = Decimal.ToInt32(val);

    return true;
}

1
请注意,在“false”路径中仍需要分配给intval - Anthony Pegram

4
我会为decimal类编写一个扩展方法,代码如下:
public static class Extensions
{
    public static bool TryConvertToInt32(this decimal decimalValue, out int intValue)
    {
        intValue = 0;
        if ((decimalValue >= int.MinValue) && (decimalValue <= int.MaxValue))
        {
            intValue = Convert.ToInt32(decimalValue);
            return true;
        }
        return false;
    }
}

您可以这样使用它:
if (decimalNumber.TryConvertToInt32(out intValue))
{
    Debug.WriteLine(intValue.ToString());
}

2

在进行转换之前,将十进制数与int.MinValueint.MaxValue进行比较。


0

使用 Int32.TryParse(string) 有什么问题吗?


我不想将十进制数转换为字符串,再将其转换回整数。这样会消耗很多性能,并且不能直接处理非整数小数。 - Superman
当然会。如果你执行 Int32.TryParse("3.14", d),你会得到一个 False 的结果。 - Roy Dictus

0
为什么你要避免捕获 OverflowException 呢?它存在的理由是有的,你应该在调用 Decimal.ToInt32() 的地方完全捕获它。异常在整个框架中被广泛使用,用户应该捕获它们。Try 方法可以帮助你解决问题,使代码更紧凑、更清晰,但在框架没有合适的方法(在这种情况下是 Decimal.TryConvertToInt32())时,捕获 OverflowException 是适当的做法。实际上,这比编写扩展类或编写自己的单独静态方法更清晰(这两种方法都涉及编写自己的代码,而框架已经为你提供了这个功能)。

1
你是在暗示应该总是捕获异常,永远不应该试图避免它们吗?如果是这样,那是错误的建议。尽可能避免它们(例如通过验证其已知原因),只有在有能力实际处理它们时才捕获它们。异常很昂贵,不应用于控制流程。 - Anthony Pegram
你说得对,我很感激你的评论。这取决于开发人员确定这种情况是罕见还是频繁发生。根据我的经验,像将Decimal.ToInt32转换时出现OverflowException这样的情况只会很少发生,异常处理程序可以很好地设置适当的结果。但这确实取决于具体情况,再次感谢你添加关于异常性能的重要说明。 - mattypiper
抛出和捕获异常是很耗费资源的。但是设置try/catch块并不会,如果导致异常的条件“几乎从不”发生,那么平均而言,这比执行验证[在转换本身中将被重复执行的验证]更便宜。 - Random832

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接