在属性中包装结构或类字段会强制对该字段的所有访问都通过“getter”和“setter”方法。这允许为验证、延迟初始化等添加逻辑。此外,在类字段的情况下,它允许一个可能具有适用于某些实例但不适用于其他实例的逻辑的可能性;如果属性不是虚拟的,则可能难以有效地实现这种逻辑(例如,可能必须定义一个 staticVerySpecialInstance
并让属性 getter 说if (this == VerySpecialInstance) GetSpecialProperty(); else GetOrdinaryProperty();
)但它可以完成。
但是,如果结构(例如System.Drawing.Point
)的语义规定可以使用对其类型合法的任何值写入特定的读写属性,则写入除了更改其值之外没有任何副作用,它将始终返回最后写入的值(如果有),如果未写入,它将作为其类型的默认值读取;如果使用该类型的代码可能依赖于这样的假设,那么我不清楚使用读写属性而不是保存该值的字段可能会带来什么好处。
Microsoft 使用属性而不是字段的事实Point.X
在历史上引起了混淆,因为MyList[3].X = 4;
它将被转换为MyList[3].Set_X(4)
,并且如果不查看定义的内部,Set_X
则不可能在不更改有问题的结构;今天的 C# 编译器会猜测它不会工作,并且会禁止该构造,即使有些struct
类型的属性设置器实际上可以正常工作。如果X
是一个字段而不是一个属性,并且如果微软说过改变结构的两种安全方法是直接访问字段或将结构作为ref
变异方法的参数(如果它是结构类型的静态方法,可以访问公共字段),则无需进行此类猜测。
鉴于使用暴露的结构字段而不是读写属性可以提高性能和语义清晰度,有什么理由将结构字段设为私有并将它们包装在属性中?数据绑定需要属性,但我认为它无论如何都不适用于结构类型(如果复制一个结构,然后将原始的某些属性设置为一个值,并将副本的相应属性设置为另一个值,那么应该使用什么值被报告给绑定对象?)结构属性有一些我不知道的好处吗?
就个人而言,我认为在许多情况下,“理想”结构只是一个公开的公共字段列表,以及一个其参数只是这些字段的初始值的构造函数,按顺序排列。这样的结构将提供最佳性能和可预测的语义(除了字段的类型和名称外,其行为与所有其他此类结构相同)。如果除了简单地读取和写入基础字段之外,它们无能为力的情况下,是否有任何理由支持读写属性?