Distinguishing between wants and needs
If you are doing WPF development you will not get very far before running into this decision. Should you use DependencyObject(and DependencyProperty) or should you implement INotifyPropertyChanged to support binding. This question boils down into two really. When do you "need" to use one or the other, and when might you "want" to choose one over the other.
So when do we need to use DependencyObject?
<MyControl MyDependencyProperty="{Binding PropertyPath}" />
The only time you must use a DependencyObject is when you want someone to be able to make it the target of a binding expression. Typically (though not always) this is only the case if you have created a custom control with properties that you want to be bindable rather than as a view model. This is the one case where you cannot use INotifyPropertyChanged.
So when do we need to use INotifyPropertyChanged?
- If your object/property needs to implement a custom Equals/Hashcode.
DependencyObject seals both Equals and GetHashCode methods, so if you need to override you must use INotifyPropertyChanged.
- If your object/property needs to be Serializable
DependencyObject is not marked as Serializable. DependencyProperty fields do not serialize correctly even if you mark them as Serializable. DependencyProperty values are not stored local to the object (if they are stored at all).
When might I want to use one over the other?
Performance (memory and speed) - DependencyObject wins
- Binding works faster with DependencyObject rather than an object that implements INotifyPropertyChanged.
- DependencyObject uses less memory than a CLR(Common Language Runtime) object.
This can be a significant difference if objects are commonly using the default values. DependencyObject uses a static field for the default, and only creates storage space for the DependencyProperty if a value is set. This is the reason a DependencyObject is not serializable.
It should be noted that in most cases you would never notice the difference. Only in cases with a very large property set, or with more real-time operations would you need the performance difference.
Multi-threaded - CLRs win
- If you are using a background thread to create your objects you might want to use CLRs instead.
DependencyObjects have thread affinity (they can only be accessed from the thread they were created on). Binding to a DependencyObject that you have created on a background thread will cause an exception.
However ....
You could dispatch your object creation to the UI thread. Keep in mind though if you are constantly having to bounce thread calls to create your objects and set values then you may be losing much of the benefit of using your background thread for processing.
Control over notification - CLRs win
- You get to decide when to send notification of changes.
This can be useful if for instance you wanted to batch multiple changes into one UI operation.
However ....
You do get other very useful mechanisms built into the DependencyObject/DependencyProperty system. Validate and Coerce callbacks are very useful in certain situations.
In conclusion....
There is no best to use for all cases. Instead you should pick the one that suits your needs. Hopefully this post has helped you to determine which one that will be!