依赖项属性的安全性
通常应将依赖属性视为公共属性。 Windows Presentation Foundation (WPF) 属性系统的性质可防止对依赖属性值进行安全保证。
包装器和依赖属性的访问和安全性
通常,依赖项属性与简化从实例获取或设置属性的“包装器”公共语言运行时(CLR)属性一起实现。 但包装器实际上只是实现与依赖属性交互时所使用的基础 GetValue 和 SetValue 静态调用的便捷方法。 以另一种方式思考,这些属性被公开为公共语言运行时(CLR)属性,这些属性恰好由依赖属性而不是私有字段提供支持。 应用于包装器的安全机制与属性系统行为以及基础依赖属性的访问并不可比。 对包装器提出安全要求仅阻止使用便捷方法,但不会阻止对 GetValue 或 SetValue 的调用。 同样,在包装器上放置受保护的或专用访问级别不提供任何有效的安全性。
如果要编写自己的依赖属性,应当将包装器和 DependencyProperty 标识符字段声明为公共成员,以便调用方(由于它的存储是作为依赖属性实现的)不会获得有关该属性的实际访问级别的误导信息。
对于自定义依赖属性,可以将属性注册为只读依赖属性,而且这确实提供了一种有效的方法来防止属性被任何不拥有对该属性的 DependencyPropertyKey 的引用的人设置。 有关详细信息,请参阅 Read-Only 依赖项属性。
说明
不禁止将 DependencyProperty 标识符字段声明为私有字段,而且可以放心地使用这种方法来帮助减小自定义类的直接公开命名空间,但是这种属性的“私有”性质不应当被视为与公共语言运行时 (CLR) 语言定义所定义的私有访问级别一样,具体原因将在下一节介绍。
依赖属性的属性系统公开
它通常没有用处,而且可能误导性地将 DependencyProperty 声明为除公共以外的任何访问级别。 该访问级别设置仅阻止某人从声明类获取对实例的引用。 但属性系统有几个方面将返回 DependencyProperty 作为标识特定属性的方法,因为它存在于类实例或派生类实例上,即使原始静态标识符声明为非公共,此标识符仍可在 SetValue 调用中使用。 此外,OnPropertyChanged 虚拟方法接收任何更改值的现有依赖属性的信息。 此外,GetLocalValueEnumerator 方法返回具有本地设置值的实例上任何属性的标识符。
验证和安全性
下面的安全机制不足以保证安全:向 ValidateValueCallback 应用一个要求,并期望在该要求未满足时验证失败以防止设置属性。 如果恶意调用方在应用程序域中操作,则这些调用方还可能会禁止通过 ValidateValueCallback 强制执行的 set-value 失效。