2013-05-06 2 views
2

Назначение целого числа двойнику очень легально.Почему присваивание целочисленного значения двойным прикрепленным свойствам дает ошибку?

Если мы можем сделать

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

В приведенном выше коде я случайно назначенный 0 в new FrameworkPropertyMetadata(0) и код побежал успешно.

Но у меня создалось впечатление, что вы можете назначить DataType с меньшей точностью (т. Е. Integer) с DataType с большей точностью (т. Е. 0.0 Double)?

Тогда почему это отклонение от базовой концепции программирования для свойств зависимостей?

+0

Вы могли бы ожидать, что это будет, но это не так. Вы должны назначить ожидаемый тип. И если это 'double', либо назначить 3.0 или (двойной) 3. –

+0

@ bash.d: Я знаю это, но почему это. Присвоение целочисленного значения двойному закону. –

+1

Я часто сталкивался с этой ошибкой, что в конечном итоге редактировал мои фрагменты кода для зависимостей и вложенных свойств, поэтому значение по умолчанию всегда 'default ($ type $)' ... –

ответ

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, поэтому он не может использовать встроенное преобразование; все, что он может сделать, это сбросить значение в тип, указанный разработчиком.

4

Вы не выполняете (простое) задание. Значение по умолчанию сохраняется как ссылка (в штучной упаковке), а затем свойство пытается получить значение по умолчанию в качестве указанного типа (double). Короче говоря, этот код эквивалентен:

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

Решение, конечно, очень просто:

object x = 1.0;  // boxed double 
double d = (double)x; // OK 
Смежные вопросы