从double转换为int的最佳(最安全)方式

Joe*_*l B 14 c# explicit type-conversion tryparse

我很好奇将double转换为int的最佳方法.运行时安全是我的主要关注点(它不一定是最快的方法,但这将是我的次要问题).我已经留下了一些我可以在下面提出的选项.任何人都可以权衡哪种是最佳做法?有没有更好的方法来实现这个我没有列出?

        double foo = 1;
        int bar;

        // Option 1
        bool parsed = Int32.TryParse(foo.ToString(), out bar);
        if (parsed)
        {
            //...
        }

        // Option 2
        bar = Convert.ToInt32(foo);

        // Option 3
        if (foo < Int32.MaxValue && foo > Int32.MinValue) { bar = (Int32)foo; }
Run Code Online (Sandbox Code Playgroud)

Ani*_*Ani 27

我认为你最好的选择是:

checked
{
    try
    {
        int bar = (int)foo;
    }
    catch (OverflowException)
    {
     ...          
    }
}
Run Code Online (Sandbox Code Playgroud)

来自显式数字转换表

"当你从一个双键或浮点值,为整型转换,该值被截断.如果得到的积分值是目标值的范围之外,则结果取决于溢出检查上下文.在一个最好的上下文中,发生OverflowException被抛出,而在一个未经检查的情况下,结果是目标类型的一个未指定的值".

注意:选项2也会OverflowException在需要时抛出.


Gra*_*ton 6

我更喜欢选项2.

您需要做的一件事是检查异常但确认它有效,就像您在选项1中检查'已解析'一样:

try
{
    bar = Convert.ToInt32(foo); 
}
catch(OverflowException)
{
    // no can do!
{
Run Code Online (Sandbox Code Playgroud)

如果您要转换字符串等而不是double,则可能会获得"FormatException".

编辑

我最初说选项2并不比选项1特别好,@ 0xA3指出错误.选项1更糟糕,因为它在被解析为整数之前转换为字符串,这意味着效率较低.如果double超出整数范围(您可能想要或可能不想要),也不会得到OverflowException - 虽然在这种情况下'parsed'将为False.


Max*_*ffe 6

选项 3a 不使用异常,始终返回一个值:

    Int32 Convert(Double d)
    {
        if (d <= (double)Int32.MinValue)
            return Int32.MinValue;
        else if (d >= (double)Int32.MaxValue)
            return Int32.MaxValue;
        else 
            return (Int32)d;
    }
Run Code Online (Sandbox Code Playgroud)


Edw*_*eno 5

我意识到这不是OP要求的,但这个信息可能很方便.

这是一个比较(来自http://www.dotnetspider.com/resources/1812-Difference-among-Int-Parse-Convert-ToInt.aspx)

        string s1 = "1234";
        string s2 = "1234.65";
        string s3 = null;
        string s4 = "12345678901234567890123456789012345678901234567890";

        int result;
        bool success;

        result = Int32.Parse(s1);      // 1234
        result = Int32.Parse(s2);      // FormatException
        result = Int32.Parse(s3);      // ArgumentNullException
        result = Int32.Parse(s4);      // OverflowException

        result = Convert.ToInt32(s1);      // 1234
        result = Convert.ToInt32(s2);      // FormatException
        result = Convert.ToInt32(s3);      // 0
        result = Convert.ToInt32(s4);      // OverflowException

        success = Int32.TryParse(s1, out result);      // 1234
        success = Int32.TryParse(s2, out result);      // 0
        success = Int32.TryParse(s3, out result);      // 0
        success = Int32.TryParse(s4, out result);      // 0
Run Code Online (Sandbox Code Playgroud)