依赖项属性的安全性

依赖属性通常应当被视为公共属性。 Windows Presentation Foundation (WPF) 属性系统在本质上无法对依赖属性值提供安全保证。

包装器和依赖属性的访问和安全性

通常,依赖属性是随“包装器”公共语言运行时 (CLR) 属性一起实现的,这些包装器属性可以简化从实例获取或设置属性的过程。 但包装器实际上只是实现与依赖属性交互时所使用的基础 GetValueSetValue 静态调用的便捷方法。 从另外一个角度考虑,这些属性作为恰好由依赖属性(而非私有字段)支持的公共语言运行时 (CLR) 属性公开。 应用于包装器的安全机制与属性系统行为以及基础依赖属性的访问并不可比。 对包装器提出安全要求仅阻止使用便捷方法,但不会阻止对 GetValueSetValue 的调用。 同样,为包装器设置受保护或私有访问级别也不会提供任何有效的安全性。

如果要编写自己的依赖属性,应当将包装器和 DependencyProperty 标识符字段声明为公共成员,以便调用方(由于它的存储是作为依赖属性实现的)不会获得有关该属性的实际访问级别的误导信息。

对于自定义依赖属性,可以将属性注册为只读依赖属性,而且这确实提供了一种有效的方法来防止属性被任何不拥有对该属性的 DependencyPropertyKey 的引用的人设置。 有关详细信息,请参阅只读依赖属性

注意

不禁止将 DependencyProperty 标识符字段声明为私有字段,而且可以放心地使用这种方法来帮助减小自定义类的直接公开命名空间,但是这种属性的“私有”性质不应当被视为与公共语言运行时 (CLR) 语言定义所定义的私有访问级别一样,具体原因将在下一节介绍。

依赖属性的属性系统公开

DependencyProperty 声明为公共级别以外的任何访问级别通常毫无用处而且可能会产生误导作用。 该访问级别设置只是防止某人从声明类获得对实例的引用。 但是,属性系统有几个方面会返回 DependencyProperty 作为一种标识在类实例或派生类实例上存在的特定属性的方式,而且该标识符在 SetValue 调用中仍可用,即使最初的静态标识符声明为非公共也是如此。 此外,OnPropertyChanged 虚拟方法接收任何更改值的现有依赖属性的信息。 此外,GetLocalValueEnumerator 方法返回具有本地设置值的实例上的任何属性的标识符。

验证和安全

下面的安全机制不足以保证安全:向 ValidateValueCallback 应用一个要求,并期望在该要求未满足时验证失败以防止设置属性。 如果恶意调用方在应用程序域中操作,则这些调用方还可能会禁止通过 ValidateValueCallback 强制执行的 set-value 失效。

另请参阅