将正交结构字段包装在与值无关的读写属性中是否有用



将结构或类字段包装在属性中会强制对该字段的所有访问都通过"getter"和"setter"方法。 这允许添加用于验证、延迟初始化等的逻辑。 此外,在类字段的情况下,它允许一种可能性,即可能具有适用于某些实例但不适用于其他实例的逻辑;如果属性不是虚拟的,则可能很难有效地实现这样的逻辑(例如,可能必须定义一个静态VerySpecialInstance并让属性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是一个字段而不是一个属性,并且如果Microsoft说过改变结构的两种安全方法是直接访问字段或将结构作为ref参数传递给变异方法(如果它是结构类型的静态方法,则可以访问公共字段), 这种猜测是没有必要的。

鉴于使用公开的结构字段而不是读写属性可以提高性能和语义清晰度,存在哪些理由将结构字段设为私有并将它们包装在属性中? 数据绑定需要属性,但我认为它无论如何都不适用于结构类型(如果复制结构,然后将原始属性的某些属性设置为一个值,将副本的相应属性设置为另一个值,则应向绑定对象报告什么值? 结构属性是否有一些我不知道的好处?

就个人而言,我认为在许多情况下,"理想"结构只是公开的公共字段列表,以及一个构造函数,其参数只是这些字段的初始值。 这样的结构将提供最佳性能和可预测的语义(除了字段的类型和名称之外,其行为与所有其他此类结构相同)。 在除了简单地读取和写入基础字段之外,它们无能为力的情况下,是否有任何理由支持读写属性?

看不到使用read/write属性的不可变结构的任何好处,除了你写的一点:将逻辑包装在属性的setter和/或getter中,并在整个代码库中维护一般准则(有利于维护和可读性的观点)。

我个人在定义一个struct几乎总是使用原始public字段而没有属性,为了简单和易于使用我的类型(对于您已经编写的不可变类型的问题)

希望这有帮助。

Rico Mariani 写了一篇关于这个主题的很好的 MSDN 博客文章。

使用公共字段而不是getter和setter的原因包括:

  1. 不允许该字段具有任何值。
  2. 客户端应对其进行编辑。
  3. 能够编写诸如对象之类的东西。X.Y = Z。
  4. 做出一个强有力的承诺,即价值只是一个价值,没有与之相关的副作用(将来也不会)。

有些人觉得这很有争议。我怀疑这是因为列出的案例很少或从未出现在他们编写的软件中,但他们没有意识到在其他应用领域中他们出现了很多。

(这是我在这里提供的答案的副本,但我认为这些信息足够有用,可以在这里重复。

最新更新