INotifyPropertyChanged与DependencyProperty

时间:2009-02-20 18:13:42

标签: c# .net wpf

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

注意:是的,我已阅读其他问题INotifyPropertyChanged vs. DependencyProperty in ViewModel

6 个答案:

答案 0 :(得分:21)

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

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

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

<强>更新

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

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

答案 1 :(得分:13)

没关系,我刚刚在以下question中找到了我想要的答案。

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


实现INotifyPropertyChanged比DependencyObjects有很多优点(我将缩写此DO以使其更容易)并使用DependencyProperties(DPs):

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

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

  • 特别适合初学者使用。
  • 您可以免费获得一个回调机制(几乎),允许您在属性值更改时收到通知
  • 您可以使用强制机制来定义属性的最大值,最小值和现值的规则。

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

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

HTH,Laurent

答案 2 :(得分:11)

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

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

假设3D坐标轴。我们添加了 x y z 等标签靠近每个轴。 WPF中的3D文本渲染是相对艰苦的工作WPF 3D Perfomance

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

  1. 方法 - INotifyPropertyChanged包括)

    Public Property T3D_LabelAngleX()As Double 得到 返回_T3D_LabelAngleX 结束了 设置(ByVal值为Double) _T3D_LabelAngleX =值 t3d_SetLabelTransform() 结束集 结束财产

  2. 方法 - DP

    Public Shared ReadOnly MDS_AngleLabelRotation_XProperty As DependencyProperty = _ DependencyProperty.Register(“MDS_AxisAngleRotation_X”,_ GetType(Double),GetType(MainDecartsSystem),_ 新的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_RotationChanged t3d_SetLabelTransform() 相等Labels in rotation...。 我可怜的老鼠...... 两者都很快!我无法发现任何差异。似乎DP有点快,可能......(我不确定)。谢谢你的问题。