I am reading Adam Nathan's book "WPF 4 Unleashed" and there is the following warning on page 82:
.NET property wrappers are bypassed at runtime when setting dependency properties in XAML!
Although the XAML compiler depends on the property wrapper at compile time, WPF calls the underlying GetValue and SetValue methods directly at runtime! Therefore, to maintain parity between setting a property in XAML and procedural code, it’s crucial that property wrappers not contain any logic in addition to the GetValue/SetValue calls. If you want to add custom logic, that’s what the registered callbacks are for. All of WPF’s built-in property wrappers abide by this rule, so this warning is for anyone writing a custom class with its own dependency properties.
My question is: Why? What are the reasons that WPF calls GetValue()/SetValue() instead of reading/setting a CLR property wrapper? If the reason is that reading/setting a property wrapper requires reflection, then WPF uses reflection much when constructing an object tree anyway, so is it really worth it to bypass using property wrappers and call GetValue()/SetValue() directly? Or avoiding Reflection is not the main reason for such a behavior?
UPD. Clemens quickly gave a correct answer, but I would add just one more quote from that MSDN page (as I understand StackOverflow prefers quotes to links):
The type is looked up through a combination of xmlns and assembly attributes, but identifying the members, determining which could support being set as an attribute, and resolving what types the property values support would otherwise require extensive reflection using PropertyInfo. Because dependency properties on a given type are accessible as a storage table through the property system, the WPF implementation of its XAML processor uses this table and infers that any given property ABC can be more efficiently set by calling SetValue on the containing DependencyObject derived type, using the dependency property identifier ABCProperty.
The explanation is given in XAML Loading and Dependency Properties:
and: