INotifyPropertyChanged与DependencyProperty

我需要观察属性的变化。 在性能和内存使用方面哪种方法更好:实现INotifyPropertyChanged或使用DependencyProperty

注意:是的,我在ViewModel中已经阅读了另一个问题INotifyPropertyChanged与DependencyProperty 。

内存使用:INotifyPropertyChanged是一个接口,因此接近零内存开销。 “接近于零”因为我假设您将编写一个OnPropertyChanged方法,并且可能在其他类中编写一些事件处理程序(除非您真的只是在讨论绑定到WPF),因此会有轻微的代码开销。

性能:DependancyProperties有很多内容。 除非您编写有史以来最不具有性能的OnPropertyChanged方法,否则我会打赌INotifyPropertyChanged也将成为优胜者。

除非你有一个明确的理由想要/需要DP提供的行为,否则我会选择INotifyPropertyChanged。

更新

正如评论所提到的那样,对于DP来说,绑定性能要快一些(由于直接属性的查找/连接所需的reflection量,快15-20%,但仍然只有不到50毫秒的1000个绑定)。 这在技术上与更新数据绑定UI元素的性能不同,这是我的评论所面向的。 但这并不意味着我的赌注也是正确的。 所以一些示例和很多.NET Reflector挖掘机后来看起来……没有定论。 两条路径都做了大量的工作,我无法得到任何示例来显示更新性能的明确差异。

除非我特别需要DP,否则我仍然坚持使用INotifyPropertyChanged,但这至少是一个有趣的练习,可以更多地探讨WPF核心。 🙂

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

为了方便起见,我会将“LBugnion”的答案重新发布(所以所有功劳都归他所有):


实现INotifyPropertyChanged比DependencyObjects有很多优点(我将简化这个DO以使其更容易)并使用DependencyProperties(DPs):

  • 这更轻巧
  • 允许您更自由地建模对象
  • 可以轻松序列化
  • 您可以在需要时引发事件,这在某些情况下很有用,例如,当您只想在一个UI操作中捆绑多个更改时,或者即使数据没有更改也需要引发事件(到强制重绘…)

另一方面,在WPF中inheritanceDO具有以下优点:

  • 更容易实施,尤其适合初学者。
  • 您可以免费获得回调机制(几乎),允许您在属性值更改时收到通知
  • 您将获得强制机制,允许您定义属性的最大值,最小值和现值的规则。

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

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

HTH,Laurent

正如MSDN所说,使用INotifyPropertyChanged,WPF绑定到DependencyProperties比使用自定义CLR对象更快。

请参阅http://msdn.microsoft.com/en-us/library/bb613546.aspx

恕我直言,INotifyPropertyChanged非常轻巧,与DP相比易于使用。 就性能/内存而言,你真的需要知道吗? Knuth想知道。

显然,您必须确定您的要求,并查看您希望创建/秒的DP数量,它们的使用寿命以及运行一些测试。 我以前做过这个,并没有看到以~10k / sec(YMMV)创建短寿命DP的任何问题。

我建议你提出错误的问题。 而不是询问性能,你应该看看每种方法的function和好处。 基本上,决定使用哪个不应该基于性能。 从读取的内容我已经完成了如果你正在创建一个控件然后你应该使用dependencyProperty,否则使用INotifyPropertyChanged。

这是一个非常有趣和重要的问题恕我直言。 我在下一个纯粹(没有绑定)任务上测试了它。 DP作为一个事实必须非常快……(100 ..每个标准控件的属性,动画) 所以,问题是

假设3D坐标轴。 我们在每个轴附近放置了xyz等标签。 WPF中的3D文本渲染是相对努力的WPF 3D Perfomance

当标签直接显示给用户时,任务是在3D场景中鼠标旋转时检测旋转检测标签(在3D场景旋转时,它们用轴平移但是通过特殊方式旋转)。 此任务由相同的CallBack函数解决。 实现如下:

  1. 方法 – INotifyPropertyChanged包括)

    公共属性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

    公共共享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()相等的轮换标签...... 。 我可怜的老鼠……两个都很快! 我无法发现任何差异。 似乎DP有点快,可能……(我不确定)。 谢谢你的问题。