Why are .NET property wrappers bypassed at runtime

2019-01-07 00:46发布

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.

标签: .net wpf xaml
1条回答
老娘就宠你
2楼-- · 2019-01-07 01:22

The explanation is given in XAML Loading and Dependency Properties:

The current WPF implementation of its XAML processor is inherently dependency property aware. The WPF XAML processor uses property system methods for dependency properties when loading binary XAML and processing attributes that are dependency properties. This effectively bypasses the property wrappers. When you implement custom dependency properties, you must account for this behavior and should avoid placing any other code in your property wrapper other than the property system methods GetValue and SetValue.

and:

For implementation reasons, it is computationally less expensive to identify a property as a dependency property and access the property system SetValue method to set it, rather than using the property wrapper and its setter. This is because a XAML processor must infer the entire object model of the backing code based only on knowing the type and member relationships that are indicated by the structure of the markup and various strings.

查看更多
登录 后发表回答