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

查看:15
本文介绍了在 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和程序集组合查找类型属性,但识别成员,确定哪些可以支持被设置为一个属性,并解决什么类型否则,属性值支持将需要广泛的反思使用属性信息.因为给定类型的依赖属性是通过属性系统 WPF 作为存储表访问其 XAML 处理器的实现使用此表并推断通过调用 SetValue 可以更有效地设置任何给定的属性 ABC在包含 DependencyObject 派生类型上,使用依赖项属性标识符 ABCProperty.

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 实现本质上是依赖属性知道.WPF XAML 处理器使用属性系统加载二进制 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.

和:

出于实施原因,计算成本较低将属性标识为依赖属性并访问该属性System 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天全站免登陆