【发布时间】:2013-01-24 07:17:29
【问题描述】:
我似乎有一个奇怪的习惯……至少我的同事是这样说的。我们一直在一起做一个小项目。我编写类的方式是(简化示例):
[Serializable()]
public class Foo
{
public Foo()
{ }
private Bar _bar;
public Bar Bar
{
get
{
if (_bar == null)
_bar = new Bar();
return _bar;
}
set { _bar = value; }
}
}
所以,基本上,我只在调用 getter 并且该字段仍然为空时初始化任何字段。我认为这将通过不初始化任何未在任何地方使用的属性来减少过载。
ETA:我这样做的原因是我的类有几个属性,它们返回另一个类的实例,而另一个类的实例又具有更多类的属性,依此类推。调用顶级类的构造函数随后会调用所有这些类的所有构造函数,而并非总是都需要它们。
除了个人喜好之外,对这种做法有什么反对意见吗?
更新:关于这个问题,我考虑了许多不同的意见,我会坚持我接受的答案。不过,我现在对这个概念有了更好的理解,我能够决定何时使用它,何时不使用它。
缺点:
- 线程安全问题
- 当传递的值为 null 时不服从“setter”请求
- 微优化
- 异常处理应在构造函数中进行
- 需要检查类代码中的空值
优点:
- 微优化
- 属性永远不会返回 null
- 延迟或避免加载“重”对象
大多数缺点不适用于我当前的库,但是我必须测试一下“微优化”是否真的在优化任何东西。
最后更新:
好的,我改变了答案。我最初的问题是这是否是一个好习惯。我现在确信它不是。也许我仍然会在我当前代码的某些部分使用它,但不是无条件的,也绝对不是一直使用它。所以我会失去我的习惯,在使用它之前考虑一下。谢谢大家!
【问题讨论】:
-
这是延迟加载模式,在这里它并没有给你带来什么好处,但它仍然是一件好事。
-
如果您对性能有可衡量的影响,或者如果这些成员很少使用并且消耗过多的内存,或者如果需要很长时间来实例化它们并且只想这样做,则延迟实例化是有意义的按需提供。无论如何,请务必考虑线程安全问题(您当前的代码不是)并考虑使用提供的Lazy<T> 类。
-
我认为这个问题更适合codereview.stackexchange.com
-
@PLB 它不是单例模式。
-
我很惊讶没有人提到这段代码的严重错误。你有一个公共财产,我可以从外面设置它。如果我将其设置为 NULL,您将始终创建一个新对象并忽略我的 setter 访问。这可能是一个非常严重的错误。对于私有财产,这可能是好的。就个人而言,我不喜欢做这种过早的优化。增加了复杂性而没有额外的好处。
标签: c# coding-style getter