是不是我不应该在属性访问器中做"长时间运行"的事情?

Che*_*eso 8 c# vb.net class-design properties

如果是这样,为什么?什么构成"长跑"?

在属性访问器中做魔术似乎是我作为类设计师的特权.我一直认为这就是为什么C#的设计师把那些东西放在那里 - 所以我可以做我想要的.

当然,最好的做法是尽量减少类的用户的意外,因此在一种方法中嵌入真正长时间运行的东西 - 例如,10分钟的蒙特卡罗分析 - 是有道理的.

但是假设一个prop访问器需要db读取.我已经打开了数据库连接.在正常的期望中,db访问代码是否可以在属性访问器中"接受"?

mqp*_*mqp 22

就像你提到的那样,这对班级用户来说是一个惊喜.人们习惯于能够用属性做这样的事情(设想的例子如下:)

foreach (var item in bunchOfItems)
    foreach (var slot in someCollection)
        slot.Value = item.Value;
Run Code Online (Sandbox Code Playgroud)

这看起来非常自然,但如果item.Value每次访问它时实际上都在访问数据库,那么这将是一个小小的灾难,应该以与此相当的方式编写:

foreach (var item in bunchOfItems)
{
   var temp = item.Value;
   foreach (var slot in someCollection)
      slot.Value = temp;
}
Run Code Online (Sandbox Code Playgroud)

请帮助引导人们使用你的代码远离这样的隐患,并在方法中加入缓慢的东西让人们知道它们很慢.

当然,也有一些例外.懒惰加载是好的,只要延迟加载不会花费一些疯狂的长时间,并且有时使得属性对于反射和数据绑定相关的原因非常有用,所以也许你想要弯曲这个规则.但是,如果没有特定的理由,违反公约并违反人们的期望就没有多大意义.

  • 优秀的例子+1 (3认同)

Eri*_*ert 12

除了已经发布的好答案之外,我还要补充说,当您检查类的实例时,调试器会自动显示属性的值.您是否真的想要调试代码并每次检查类时在调试器中发生数据库提取?对代码的未来维护者要好,不要那么做.

此外," 框架设计指南"对此问题进行了广泛讨论; 考虑拿起副本.

  • 每个人都应该得到这本书! (4认同)
  • 我还了解到,最好避免在属性的getter中使用副作用进行操作.没有什么比通过观察调试器中的对象来追逐你的尾部"Heisenbugs"更糟糕的了,这会改变你的对象的状态.(见http://en.wikipedia.org/wiki/Unusual_software_bug) (3认同)