为什么将一个Integer分配给Double Attached Properties会出错?

时间:2013-05-06 12:09:17

标签: c# wpf vb.net dependency-properties attached-properties

将整数分配给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);
    }

我编译了代码。没有编译时错误。

但是当我试图运行应用程序时,它给出了错误

enter image description here

在上面的代码中,我意外地在new FrameworkPropertyMetadata(0)中分配了0,代码运行成功。

但我的印象是你可以将具有较低精度的数据类型(即整数)分配给具有更高精度的数据类型(即0.0双精度)?

那为什么这种偏离基本编程概念的依赖属性?

2 个答案:

答案 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盒装值只能取消装入其实际类型,通常的隐式数字转换(例如intdouble)在这种情况下不起作用。

以下是一个说明问题的示例:

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,因此它不能使用内置的转换;它所能做的就是将值取消包装为开发人员指定的类型。