Initialize()vs Constructor()方法,正确用于创建对象

时间:2010-12-11 00:33:06

标签: c# constructor initialization

我们都从根本上了解Constructor和用户定义的Initialize()方法之间的区别。

我的问题集中在对象创建的最佳设计实践上。我们可以将所有Initialize()代码放入Constructor(),反之亦然(将所有预热代码移至Initialize方法,并从Constructor调用此方法。)

目前,在设计新课程时,我会在constructor()中创建任何新实例,并将任何其他预热代码移至Initialize()方法。

您认为最好的权衡点是什么?

2 个答案:

答案 0 :(得分:25)

我认为应该考虑多个方面:

  • 构造函数应该以一种处于可用状态的方式初始化对象。

  • 构造函数应该只初始化一个对象,而不是执行繁重的工作。

  • 构造函数不应直接或间接调用虚拟成员或外部代码。

因此,在大多数情况下,不需要使用Initialize方法。

如果初始化涉及的不仅仅是将对象置于可用状态(例如,当需要执行繁重的工作或需要调用虚拟成员或外部时),则初始化方法是个好主意。

答案 1 :(得分:3)

我最近发现自己在考虑这个问题(因此找到了这个问题),虽然我没有答案但我认为我会分享我的想法。

  • 构造函数'理想情况下'应该只设置对象状态,即:几个:

this.member = member;

在我看来,这与IoC,继承,测试非常吻合,只是闻起来很好。

然而,有时需要举重,所以我一直想做的是:

  • 通过繁重的工作。

这意味着将初始化代码抽象到另一个类并将其传入。这通常可能是因为繁重的工作并不是您的对象责任,所以这样做实际上可以重构更好的代码。

如果这是不可能的,并且您确实需要在使用前初始化您的类的状态,那么添加一个initialse方法。这确实会在代码中添加时间依赖性,但这并不一定是坏事,尤其是在使用IoC容器时:

CarEngine需要DrivingAssistComputerDrivingAssistComputer需要进行大量初始化,即加载所有参数,天气状况检查等。另外需要注意的是{{1}不直接与CarEngine交互,它只需要它存在,在侧面做自己的事情。事实上,如果没有DrivingAssistComputer在后​​台做某事(在某处改变一些状态),引擎可能无法正常工作。如果我们使用IoC,那么我们有:

DrivingAssistComputer

所以我们这里有一个构造函数参数,将// Without initialise (i.e. initialisation done in computer constructor) public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) { this.injectors = injectors; // No need to reference computer as we dont really interact with it. } ... 标记为依赖,但实际上并未使用它。所以这很难看,但我们添加一个Initialise方法:

computer

仍然不是一个有凝聚力的类,但至少我们知道我们依赖于计算机,即使我们没有在构造函数之外直接与它进行交互。

另一个选择是使用CarEngineFactory:

public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) {
  this.injectors = injectors;
  // This ofcourse could also be moved to CarEngine.Initialse
  computer.Initialise(); 
}

...

但是,我发现工厂和IoC只是混淆矩阵,所以我会选择第二种选择。

很想听听有关这方面的一些想法。

编辑1: 我错过的另一个选项是使用Initialise方法,但将此调用移至IoC初始化模块。因此创建和初始化仍然有些封装。