受保护的成员/领域真的那么糟糕吗?
-
02-10-2019 - |
题
现在,如果您阅读了MSDN中的命名约定,您会注意到它始终比公共和受保护的领域更喜欢属性。一些人告诉我,您绝不应该使用公共或受保护的领域。现在,我同意我还没有找到需要一个公共领域的原因,但是受保护的领域真的那么糟糕吗?
如果您需要确保在获得/设置值时执行某些验证检查,我可以看到它,但是在我看来,很多时间似乎只是额外的开销。我的意思是说,我有一个带有Basename,prefixname和SuffixName的字段的班级游戏。我为什么要掌握两个创建属性的开销(C#
)或访问者方法以及我将发生的性能(如果我为应用程序中的每个字段执行此操作),我相信它会添加少一点 PHP
还是某些具有性能的应用程序像游戏一样至关重要)?
解决方案
受保护的成员/领域真的那么糟糕吗?
不,它们是更糟的。
一旦成员比 private
, ,您正在向其他班级保证该成员的行为方式。由于一个字段完全不受控制,因此将其“在野外”开放,可以打开您的课堂和类,这些课程从您的班级继承或与您的班级进行互动,以提高错误风险。没有办法知道何时改变字段,无法控制谁或什么变化。
如果现在或将来的某个时刻,您的任何代码都取决于某个字段某种值的值,现在您必须添加有效性检查和后备逻辑,以防它不是预期值 - 您使用它的每个地方。当您可以将其成为该死的财产时,这是浪费的巨大努力;)
这 最好的 与派生类共享信息的方法是 仅阅读属性:
protected object MyProperty { get; }
如果你绝对 有 为了读/写,不要。如果您真的必须使它读写,请重新考虑您的设计。如果您仍然需要阅读文字,请向您的同事道歉,不要再做一次:)
许多开发人员相信 - 并会告诉您 - 这过于严格。的确你可以 通过 很好,没有这么严格。但是,采用这种方法将有助于您从仅通过到达非常强大的软件。您将花费更少的时间修复错误。
并且关于性能的任何担忧 - 不要。我保证您永远不会在整个职业生涯中如此快地编写代码,以至于瓶颈本身就是呼叫堆栈。
其他提示
好的,降价时间。
首先,属性永远不会伤害性能(只要它们做得不多)。这就是其他人所说的话,我同意。
另一点是属性很好,您可以在其中放置断点以捕获/设置事件并找出它们的来源。
其余的论点以这种方式困扰着我:
他们听起来像是“声望的争论”。如果MSDN说了,或者每个人都喜欢的一些著名开发人员或作家 必须 是这样。
它们基于这样的想法,即数据结构具有许多不一致的状态,必须保护不足或放入这些状态。由于(在我看来)数据结构在当前的教学中被过度强调,因此通常 做 需要这些保护。更可取的是 最小化数据结构 因此,它倾向于将其标准化,并且不会具有不一致的状态。然后,如果更改了班级的成员,则简单地更改而不是损坏。毕竟,以某种方式/在C中写了很多好的软件,并且并没有因为缺乏保护而遭受很大的影响。
它们是基于防御性编码的。这是基于这样的想法,即您的课程将在一个没有其他人可以信任的世界中使用的世界。我敢肯定在某些情况下是真的,但是 我有 从未见过他们。我什么 有 看到的情况使事情变得非常复杂,可以解决无需的保护,并试图保护数据结构的一致性,这些数据结构的一致性非常复杂且不正常。
关于字段与属性,我可以想到偏爱公共界面中属性的两个原因(从某种意义上说,除了您的班级外,受保护也是公开的)。
暴露属性为您提供隐藏实现的方法。它还允许您在不更改使用代码的情况下更改实现(例如,如果您决定更改类数据存储在类中的方式)
许多使用反思与类合作的工具仅关注属性(例如,我认为某些用于序列化的库是这样工作的)。使用属性始终如一地使使用这些标准.NET工具更容易。
关于开销:
如果getter/setter是通常只读取/设置字段值的常规代码,则JIT应该能够嵌入呼叫,因此没有性能过度。
当您使用自动实现的属性(C#3.0和更新)时,句法开销大大减少,因此我认为这不是一个问题:
protected int SomeProperty { get; set; }
实际上,这使您可以做
set
受保护和get
公众很容易,因此比使用字段更优雅。
公共和/或受保护的领域很糟糕,因为它们可以在没有验证的情况下从声明类的外部操纵;因此,可以说它们打破了面向对象的编程的封装原理。
当您失去封装时,您将失去宣布阶级的合同;您不能保证班级的行为符合预期或预期。
使用属性或方法访问该字段,使您能够维护封装,并履行声明类的合同。
我同意只读的属性答案。但是要在这里扮演魔鬼的倡导者,这确实取决于您在做什么。我很乐意承认我一直与公共成员一起编写代码(我也不发表评论,遵循指南或任何手续)。
但是当我在工作时,这是另一回事。