将整数分配给double是非常合法的。
如果我们能做到
double d = 3;
d被指定为3.0
但为什么在附加属性中失败?
方案
我创建了附属物
public static readonly DependencyProperty ActualWidthBeforeHidingProperty =
DependencyProperty.RegisterAttached("ActualWidthBeforeHiding",
typeof(double), typeof(MainWindow), new FrameworkPropertyMetadata(0));
public static double GetActualWidthBeforeHiding(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return Convert.ToDouble(element.GetValue(ActualWidthBeforeHidingProperty));
}
public static void SetActualWidthBeforeHiding(DependencyObject element, double value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(ActualWidthBeforeHidingProperty, value);
}
我编译了代码。没有编译时错误。
但是当我试图运行应用程序时,它给出了错误
在上面的代码中,我意外地在new FrameworkPropertyMetadata(0)
中分配了0,代码运行成功。
但我的印象是你可以将具有较低精度的数据类型(即整数)分配给具有更高精度的数据类型(即0.0双精度)?
那为什么这种偏离基本编程概念的依赖属性?
答案 0 :(得分:4)
你没有做(简单)任务。默认值存储为引用(boxed int),稍后属性尝试将默认值作为指定类型(double)。简而言之,此代码是等效的:
object x = 1; // boxed int
double d = (double)x; // InvalidCast exception
解决方案当然很简单:
object x = 1.0; // boxed double
double d = (double)x; // OK
答案 1 :(得分:3)
这是因为boxing:
FrameworkPropertyMetadata
构造函数的参数声明为object
,因此当您执行new FrameworkPropertyMetadata(0)
时,整数值0
会被设置为object
(因为int
是值类型)。当WPF尝试使用此默认值时,它会尝试将其解除绑定到double
(因为该属性被声明为double
),但由于框内值为int
而失败,因此一个double
。 盒装值只能取消装入其实际类型,通常的隐式数字转换(例如int
到double
)在这种情况下不起作用。
以下是一个说明问题的示例:
int i = 42;
double d1 = i; // Works fine, uses the built-in conversion from int to double
object o = i; // boxing
double d2 = (double)o; // Fails: unboxing to the wrong type
编译器静态地不知道该对象实际上是一个盒装的int,因此它不能使用内置的转换;它所能做的就是将值取消包装为开发人员指定的类型。