你应该在课堂上使用访问者属性,还是只从课堂外使用?

我有一个类’Data’,它使用getter来访问某个数组。 如果数组为null,那么我希望Data访问该文件,填充数组,然后返回特定值。

现在这是我的问题:

在创建getter和setter时,您是否也应该使用相同的访问器属性作为访问该arrays的方式(在本例中)? 或者你应该直接访问数组?

我在类中使用访问器的问题是,当调用类在Data.array中查找某些信息时,我得到无限循环,getter发现数组为null,所以从文件中获取它,并且该函数结束再次从Data中调用getter,数组再次为null,并且我们陷入无限循环。

编辑:

那么对此没有官方立场吗? 我看到不使用具有文件访问权限的Accessors的智慧,但是你们中的一些人总是说要在类中使用访问器,而其他人则说从不使用类中的访问器……… ……………………………..

我同意krosenvold,并想稍微概括一下他的建议:

不要将Property getters和setter用于昂贵的操作,例如读取文件或访问网络。 对显示昂贵的操作使用显式函数调用。

通常,类的用户不会期望简单的属性检索或赋值可能花费很多时间。

这也是Microsoft的框架设计指南中的建议。 ;

在以下情况下,请使用方法而不是属性

该操作比字段集慢几个数量级。 如果您甚至考虑提供异步版本的操作以避免阻塞线程,则很可能操作过于昂贵而无法成为属性。 特别是,访问网络或文件系统的操作(初始化除了一次)应该最有可能是方法,而不是属性。

我认为总是使用访问器是一个好主意。 然后,如果在获取或设置属性时需要任何特殊逻辑,您就知道一切都在执行该逻辑。

你可以为其中一个属性发布getter和setter吗? 也许我们可以帮助调试它。

我写了一个打开文件的getter,后来总是后悔。 现在,我永远不会通过延迟构建来解决这个问题。 存在副作用的吸气剂问题,人们不希望在吸气剂后面发生各种疯狂的活动。 此外,您可能必须确保线程安全,这可能进一步污染此代码。 每次执行此操作时,unit testing也会变得稍微困难​​一些。

显式构造是一种比各种惰性初始吸气剂更好的解决方案。 这可能是因为我正在使用DI框架,它将所有这些作为标准使用模式的一部分。 我真的试图尽可能清楚地处理构造逻辑而不是隐藏太多,它使代码更容易理解。

不,我不相信你应该,原因:可维护的代码。

我见过人们在定义类中使用属​​性,起初看起来都很好看。 然后其他人出现并添加了属性的function,然后其他人出现并试图改变课程,他们并不完全理解课程,所有地狱都松了一口气。

它不应该因为维护团队应该完全理解他们想要改变什么,但是他们经常会查看不同的问题或错误,并且封装的属性经常会逃脱它们。 我已经看到了很多,因此从不在内部使用属性。

它们也可能是一个性能受损,如果有人将数据库代码放入属性中,那么简单的查找可能会变得令人讨厌 – 我也看到人们也这样做了!

这些年来,KISS原则仍然有效……!

除了其他人提出的观点之外,是否直接使用访问者或字段可能需要通过语义来告知。 有时,访问属性的外部使用者的语义与通过内部代码访问其值的机械必要性不同。

Eric Lippert最近在几篇文章中发表了关于这个主题的博客:

自动VS-明确的属性
适应未来发展-A-设计

如果使用Get方法导致此类错误,则应直接访问该值。 否则,最好使用您的访问者。 如果您应该修改getter或setter以便将来采取特定操作,那么如果您未能使用该路径,则会破坏您的对象。

我想你想要实现的是某种延迟加载属性,只有在第一次访问数据时才加载数据。

在这种情况下,我会使用以下方法来防止无限循环:

private MyData _data = null; public MyData Data { get { if (_data == null) _data = LoadDataFromFile(); return _data; } } private MyData LoadDataFromFile() { // ... } 

换一种说法:

  • 不要实现setter
  • 始终使用该属性访问数据(从不直接使用该字段)

你应该总是使用访问器,但是只有在必须从文件中读取值时才应该调用从文件中读取值的函数(应该是私有的,并且调用类似getValueFromFile的函数),并且应该只读取文件并返回值。 在另一个类中,该函数甚至可能会更好,专门用于从数据文件中读取值。

如果我理解正确,那么您正尝试从其实现中访问属性(通过使用在属性的实现代码中调用相同属性的方法)。 我不确定是否有任何关于此的官方标准,但我认为这是一种不好的做法,除非有特定需要这样做。

我总是喜欢在类中使用私有成员而不是属性,除非我需要function属性实现提供。