1

在属性中包装结构或类字段会强制对该字段的所有访问都通过“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变异方法的参数(如果它是结构类型的静态方法,可以访问公共字段),则无需进行此类猜测。

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

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

4

2 回答 2

1

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

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

希望这可以帮助。

于 2012-08-17T16:09:38.240 回答
1

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

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

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

有些人觉得这很有争议。我怀疑这是因为在他们编写的软件中很少或从未出现过这种情况,但他们没有意识到在其他应用领域中也经常出现这种情况。

(这是我在此处提供的答案的副本,但我认为该信息非常有用,可以在此处重复。)

于 2015-07-09T10:03:52.657 回答