双重除法时.NET无效的强制转换异常

时间:2009-10-29 15:31:41

标签: c# .net

我正在使用.NET应用程序来使用ImageMagick来减少图像文件的大小。我的应用程序在Hashtable中存储了一些“设置”,以便在应用程序的各个区域中使用。我现在正在添加一个功能,以根据转换后的图像中所需的DPI来缩小图像大小。基本上,我在未改变的图像中查找DPI,计算所需DPI相对于当前DPI的百分比,然后我将按此比例调整图像尺寸。

ImageMagick将图像DPI报告为浮点值。所以200x200 DPI真的是199.975x199.975。因此,我使用Math.Ceiling()将值输入到我的应用程序中。当我尝试使用我的设置Hashtable中所需的DPI来进行百分比计算时,我得到了无效的强制转换异常。我不知道为什么会这样。

这是一个测试用例,其失败方式与我的实际代码相同:


using System;
using System.Collections;

namespace typetest
{
    class Program
    {
        private struct DPI {
            public double x;
            public double y;
        }

        public static void Main(string[] args)
        {
            Hashtable vars = new Hashtable();
            DPI dpi;
            string dpiString = "199.547:199.547";
            string[] ret;

            vars["newDpiX"] = 150;
            vars["newDpiY"] = 150;
            ret = dpiString.Split(':');

            dpi.x = ( (double)vars["newDpiX"] / Math.Ceiling(double.Parse(ret[0])) ) * 100;
            dpi.y = ( (double)vars["newDpiY"] / Math.Ceiling(double.Parse(ret[1])) ) * 100;

            Console.WriteLine("New DPI percentage = " + dpi.x + "%x" + dpi.y +"%");
        }
    }
}

如果我将分部改为


double newDpiX = 150.0;
dpi.x = ( newDpiX / Math.Ceiling(double.Parse(ret[0])) ) * 100;

它将按预期工作。这是怎么回事?

4 个答案:

答案 0 :(得分:5)

Hashtable存储对象。当你在一个对象中放入一个int时,你会“装箱”它。拆箱需要相同的类型,不能直接从盒装int转换为double。

这将失败:

object obj = 10;
double dbl = (double)obj;

这将成功:

object obj = 10d; // a double value, could also have been 10.0
double dbl = (double)obj;

这也有效:

object obj = 10; // an int
double dbl = (double)(int)obj;

首先拆箱到一个int然后再转换为double。

编辑:

另见http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx

答案 1 :(得分:3)

尝试

vars["newDpiX"] = 150d;

答案 2 :(得分:1)

使用:

dpi.y = ( Convert.ToDouble(vars["newDpiY"]) / Math.Ceiling(double.Parse(ret[1])) ) * 100;

我认为你的问题是vars [“newDpiY”] = 150;存储一个int,而不是double。

答案 3 :(得分:0)

Hashtable hold对象,为其分配150,因此它存储为int。尝试指定150.0或(双)150或其他任何效果。