【问题标题】:Why assigning an Integer to a Double Attached Properties gives error?为什么将整数分配给双重附加属性会出错?
【发布时间】:2013-05-06 12:09:16
【问题描述】:

将 Integer 分配给 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,代码运行成功。

但我的印象是,您可以将精度较低的 DataType(即 Integer)分配给精度较高的 DataType(即 0.0 Double)?

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

【问题讨论】:

  • 您可能期望这是,但事实并非如此。您必须分配预期的类型。如果是double,则分配 3.0 或 (double)3。
  • @bash.d:我知道,但为什么会这样。将整数分配给 double 是合法的。
  • 我经常遇到这个错误,以至于我最终编辑了我的代码 sn-ps 以获取依赖项和附加属性,以便默认值始终为 default($type$)...
  • @ThomasLevesque:你如何解释如何改变它?
  • @NikhilAgrawal,使用代码 sn-ps 管理器(从工具菜单中),找到 NetFX30 sn-ps(propapropdp);它们通常位于 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC#\Snippets\1033\NetFX30 中。编辑它们以删除 defaultValue 文字声明,并将 $defaultValue$ 替换为 default($type$)

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


【解决方案1】:

你没有做一个(简单的)作业。默认值存储为引用(boxed int),稍后该属性尝试将默认值作为指定类型(双精度)。总之,这段代码是等价的:

 object x = 1;          // boxed int
 double d = (double)x;  // InvalidCast exception

解决办法当然很简单:

 object x = 1.0;        // boxed double
 double d = (double)x;  // OK

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2020-05-07
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 2015-05-07
      • 1970-01-01
      相关资源
      最近更新 更多