我遇到了StackOverflowException,这让我发现DependencyObject没有正确处理等式?!
当DependencyProperty的类型为Object
时,它将始终使用Reference.Equals
。当应用相同的值时,这会导致每次为字符串和值类型激发PropertyChanged。
如果你看看
DependencyObject。等于(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;
那么,这是一种理想的行为还是一种错误呢?
我不认为这是一个bug。它只是网络处理对象的方式。如果你在没有DependencyProperty:上下文的情况下尝试,也是一样的
我创建了一个小型控制台应用程序:
object v1 = 7;
object v2 = 7;
if (v1 == v2) Console.Write("are the same"); else Console.Write("are different");
我在控制台上读到"不一样"。因此,通常情况下,如果对象被评估为相等,那么总是通过ReferenceEquals(即使它们是装箱的值类型(。