Я столкнулся с StackOverflowException, из-за которого я обнаружил, что DependencyObject неправильно обрабатывает равенство?!
Когда свойство DependencyProperty имеет тип Object
, оно всегда будет использовать Reference.Equals
. Это заставляет каждый раз вызывать PropertyChanged для строк и типов значений, когда применяется одно и то же значение.
Если вы посмотрите на
DependencyObject.Equals (DependencyProperty dp, значение объекта 1, объект
значение2)
https://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/DependencyObject.cs,3453
/// <summary>
/// Helper method to compare two DP values
/// </summary>
private bool Equals(DependencyProperty dp, object value1, object value2)
{
if (dp.IsValueType || dp.IsStringType)
{
// Use Object.Equals for Strings and ValueTypes
return Object.Equals(value1, value2);
}
else
{
// Use Object.ReferenceEquals for all other ReferenceTypes
return Object.ReferenceEquals(value1, value2);
}
}
Простой способ воспроизвести:
public static readonly DependencyProperty ObjValueProperty = DependencyProperty.Register(nameof(ObjValue), typeof(object), typeof(MainWindow), new PropertyMetadata(default(object)));
public object ObjValue
{
get
{
return GetValue(ObjValueProperty);
}
set
{
SetValue(ObjValueProperty, value);
}
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if(e.Property == ObjValueProperty) { /*Breakpoint here*/ }
}
...
ObjValue = 7;
ObjValue = 7;
Итак, это желаемое поведение или ошибка?