为什么在XAML中设置依赖项属性时,绕过.NET属性包装器? [英] Why are .NET property wrappers bypassed at runtime when setting dependency properties in XAML?

查看:75
本文介绍了为什么在XAML中设置依赖项属性时,绕过.NET属性包装器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读亚当·内森(Adam Nathan)的著作 WPF 4 Unleashed,第82页有以下警告:

I am reading Adam Nathan's book "WPF 4 Unleashed" and there is the following warning on page 82:


。在XAML中设置依赖项属性时,将在运行时绕过NET属性包装器!

尽管XAML编译器在编译时依赖
属性包装器,但WPF调用了基础
直接在运行时使用GetValue和SetValue方法!因此,要使
在XAML中设置属性和程序性
代码之间保持均等,至关重要的是,属性包装器除了GetValue / SetValue调用外,在
中不应包含任何逻辑。如果您想添加自定义
逻辑,那就是已注册的回调函数。 WPF的所有
内置属性包装器均遵守此规则,因此,此警告是针对
编写具有自己的依赖项属性的自定义类的任何人。

.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.

我的问题是:为什么? WPF调用GetValue()/ SetValue()而不是读取/设置CLR属性包装器的原因是什么?如果原因是读取/设置属性包装器需要反射,那么WPF无论如何在构造对象树时都会使用反射,所以真的值得绕过使用属性包装器并直接调用GetValue()/ SetValue()吗?还是避免反射不是这种行为的主要原因?

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很快给出了正确的答案,但是我只想添加一个该MSDN页面上的更多报价(据我了解,StackOverflow倾向于使用引号而不是链接):

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):


通过xmlns和集合
属性,但要确定成员,确定哪些
支持可以设置为属性,并解决
属性值支持的类型,否则需要使用PropertyInfo进行广泛反射
。由于给定类型的依赖项属性可以通过属性系统作为存储表访问
,因此其XAML处理器的WPF
实现使用此表并推断
任何给定属性ABC可以更多通过使用依赖项
属性标识符ABCProperty对包含的DependencyObject派生类型调用SetValue
可以有效地进行设置。

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.


推荐答案

XAML加载和依赖关系中给出了说明属性


其XAML处理器的当前WPF实现本质上是
依赖属性的。当加载作为依赖项属性的二进制XAML和
处理属性时,WPF XAML处理器将属性系统
方法用于依赖项属性。实际上,
绕过了属性包装器。在实现自定义依赖项
属性时,必须解决此问题,并避免

属性系统方法GetValue和SetValue以外的任何其他代码放置到属性包装中。

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.

和:


出于实现原因,它在计算上
较便宜,将属性标识为依赖项属性,并访问属性
系统的SetValue方法进行设置,而不是使用属性
包装器及其设置器。这是因为XAML处理器必须仅基于了解
的类型和成员关系(由标记的
的结构和各种字符串表示)来推断
整个支持代码的对象模型。

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.

这篇关于为什么在XAML中设置依赖项属性时,绕过.NET属性包装器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆