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

时间:2009-01-24 13:32:30

标签: c# .net

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

现在这是我的问题:

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

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

编辑:

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

9 个答案:

答案 0 :(得分:6)

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

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

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

This is also recommended in Microsoft's Framework Design Guidelines.;

  

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

     

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:2)

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

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

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

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

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

答案 4 :(得分:2)

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

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

automatic-vs-explicit-properties
future-proofing-a-design

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

答案 7 :(得分:1)

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

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

private MyData _data = null;

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

private MyData LoadDataFromFile()
{
  // ...
}

换句话说:

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

答案 8 :(得分:0)

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

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