INotifyPropertyChanged与DependencyProperty的区别

19

3
为什么你不解释一下为什么另一篇文章没有给出你的答案,或者是什么让你的问题与众不同呢? - Robert P
虽然我在另一个问题中找到了答案(请参见我的回答),但我也发现Rob McCready的答案非常有帮助,这就是我选择他的答案并给他点赞的原因。谢谢大家! - user65199
6个回答

21

内存使用:INotifyPropertyChanged是一个接口,所以几乎没有内存开销。"几乎没有"是因为我假设您将编写一个OnPropertyChanged方法和其他类中的一些事件处理程序(除非您真的只是谈论绑定到WPF),因此会有轻微的代码开销。

性能:DependancyProperties在幕后有许多操作。除非您编写了最低效的OnPropertyChanged方法,否则我会打赌INotifyPropertyChanged也会成为性能胜利者。

除非您有明确定义的原因需要DP提供的行为,否则我会选择使用INotifyPropertyChanged。

更新

正如评论提到的,DP的绑定性能略高(快15-20%,但对于1000个绑定只有不到50ms的差异),这是由于需要进行查找/挂钩直接属性的反射量。这在技术上与更新数据绑定UI元素的性能不同,这是我的评论所针对的。但这并不意味着我的打赌仍然是正确的。所以通过一些示例和很多.NET Reflector挖掘之后,看起来...没有明确的差异可以证明更新性能的差异。

我仍然坚持使用INotifyPropertyChanged,除非我有特定需要DP的情况,但这至少是一个有趣的练习,可以进一步探索WPF核心。 :)


3
你的赌注似乎是错误的。请看奥里昂的回答和 MSDN 文档。动态规划更快。 - Scott Weinstein

13

没关系,我刚刚在以下问题中找到了我要寻找的答案。

以下是“LBugnion”发布的答案(所有功劳归于他):


实现INotifyPropertyChanged比DependencyObjects(DO,后面简写为DO)和使用DependencyProperties (DPs)有许多优点:

  • 更轻量级
  • 允许您更自由地对对象进行建模
  • 易于序列化
  • 您可以在想要时引发事件,在某些场景下非常有用,例如当您想要将多个更改捆绑在一个UI操作中或者当您需要引发事件即使数据没有改变(强制重绘...)

另一方面,在WPF中继承DO具有以下优点:

  • 特别是对于初学者来说,更容易实现。
  • 您可以获得(几乎)免费的回调机制,让您在属性值更改时得到通知
  • 您可以获得一个强制机制,允许您定义属性的最大、最小和存在值的规则。

还有其他考虑因素,但这些是主要考虑因素。

我认为普遍共识是,DP非常适合控件(甚至可以在Silverlight中使用自定义DP实现CustomControl),但对于数据对象,您应该实现INotifyPropertyChanged。

希望有所帮助,Laurent


11

1
我建议您正在提出错误的问题。与其询问性能,不如看看每种方法的功能和优点。基本上,使用哪种方法的决定不应该基于性能。从我所做的一些阅读来看,如果您正在创建控件,则应使用dependencyProperty,否则请使用INotifyPropertyChanged。

这并不是一个简单的方式:控制 - DP,否则 - INotifyPropertyChanged。例如,我们从ModelVisual3D继承(因此我可以实现DP)在3D图形类中。我对我的类实例在3D场景中的快速工作感兴趣。此外,我可以从FrameworkElement继承任何我的类来实现DP。在所有情况下,我感兴趣的唯一一件事就是性能! - Sergey Orlov

1

在我看来,与 DP 相比,INotifyPropertyChanged 非常轻量级且易于使用。至于性能/内存方面,您是否真的需要知道呢?Knuth 想知道。

显然,您必须确定自己的要求,并查看您期望每秒创建多少个 DP,它们的生命周期有多长,并运行几个测试。我以前做过这个,每秒创建短寿命 DP 的速度可以达到 ~10k/sec(当然,因人而异)。


1

在我看来,这是一个非常有趣和重要的问题。 我已经在下一个纯净(没有绑定)的任务上进行了测试。 DP作为事实必须非常快...(每个标准控件100个属性,可动画化) 所以,问题是

假设3D坐标轴。我们在每个轴附近放置类似于xyz的标签。WPF中的3D文本渲染相对较难 WPF 3D Perfomance

任务是检测到鼠标旋转时3D场景内的标签旋转,并且当标签直接面向用户时进行翻译(在3D场景旋转时,它们会随着轴线平移但以特殊方式旋转)。这个任务通过相同的回调函数解决。 实现如下:

  1. 方法 - INotifyPropertyChanged 包括

    Public Property T3D_LabelAngleX() As Double Get Return _T3D_LabelAngleX End Get Set(ByVal value As Double) _T3D_LabelAngleX = value t3d_SetLabelTransform() End Set End Property

  2. 方法 - DP

    Public Shared ReadOnly MDS_AngleLabelRotation_XProperty As DependencyProperty = _ DependencyProperty.Register("MDS_AxisAngleRotation_X", _ GetType(Double), GetType(MainDecartsSystem), _ New PropertyMetadata(MDS_AngleLabelRotation_XDefault, AddressOf MDS_RotationChanged))

    Public Property MDS_AngleLabelRotation_X() As Double
        Get
            Return CType(GetValue(MDS_AngleLabelRotation_XProperty), Double)
        End Get
        Set(ByVal value As Double)
            SetValue(MDS_AngleLabelRotation_XProperty, value)
        End Set
    End Property
    

    重点是 MDS_RotationChangedt3d_SetLabelTransform()相等的Labels in rotation...。 我的鼠标可怜极了.... 两者都非常快!我无法检测到任何区别。它似乎 DP 稍微快一些,可能......(我不确定)。感谢提问。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接