C# 双除法上的.NET无效强制转换异常

C# 双除法上的.NET无效强制转换异常,c#,.net,C#,.net,我正在开发一个.NET应用程序,使用.NET减少图像文件大小。我的应用程序将一些“设置”存储在哈希表中,以便在应用程序的各个领域中使用。我现在添加了一个功能,可以根据变换后的图像中所需的大小来减小图像大小。基本上,我在未更改的图像中查找DPI,计算所需DPI相对于当前DPI的百分比,然后按此比例调整图像尺寸 ImageMagick将图像DPI报告为浮点值。所以200x200dpi实际上是199.975x199.975。因此,我使用Math.天花()将值输入到我的应用程序中。当我尝试使用设置哈希表

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

ImageMagick将图像DPI报告为浮点值。所以200x200dpi实际上是199.975x199.975。因此,我使用
Math.天花()
将值输入到我的应用程序中。当我尝试使用设置
哈希表中所需的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;
它将按预期工作。这是怎么回事?

试试看

vars["newDpiX"] = 150d;
使用:


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

哈希表保存对象时,将150赋值给它,因此它存储为int。请尝试将150.0或(double)150赋值,或任何类似的值。

哈希表存储对象。当你在一个对象中放入一个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

编辑:


另请参见

150d是否会将150视为十进制而不是双精度?好的,如果我在哈希表中显式地将150存储为双精度,它会起作用。但是为什么我不能在除法时指定强制转换(不使用Convert)?对于强制转换,您必须执行(double)(int)。。首先转换成它的实际值,然后再转换成两倍。这实际上解释了我遗漏了什么。非常感谢。
object obj = 10; // an int
double dbl = (double)(int)obj;