在默认构造函数中包含代码的做法很差

时间:2013-04-26 16:12:46

标签: c# oop

我曾与一位多年从事C#体验的开发人员合作过。我不再有办法联系他了,我记得他说过将代码包含在默认参数less constructor中并不是一个好主意,但我不记得原因。

在C#或任何语言中将代码包含在默认构造函数中是不错的做法或不好的做法?

9 个答案:

答案 0 :(得分:8)

这取决于具体情况,但将代码置于默认构造函数中绝对是不错的做法。如果需要,请继续操作。

答案 1 :(得分:6)

这取决于具体情况,有时需要它,有时可以使用,有时它不应该在那里。

重要的是任何构造函数都应该将对象保持在正确的初始化状态。如果一个对象总是需要一些代码来进行初始化,但没有特定的输入来做到这一点,那么无参数构造函数将是一个很好的地方。

答案 2 :(得分:5)

想到的是Effective Java的第17项(作者Joshua Bloch):

  

第17项:继承的设计和文件,否则禁止它

他解释说构造函数不应该调用可覆盖的方法:

public class Super {
    // Broken - constructor invokes an overridable method
    public Super() {
        overrideMe();
    }
    public void overrideMe() {
    }
}

最终发生的是您正在调用超类的构造函数(当您创建子类的实例时)并且您会遇到意外行为。

如果您的构造函数确实调用了类中的其他方法,则需要在API中对此进行记录,以便在开发人员对其进行子类化时,他们将知道会发生什么。

否则,将代码放入构造函数中没有坏处。

答案 3 :(得分:2)

因为你在.NET框架中使用C#。让我为您提供MSDN完整的“构造函数设计”文章:

http://msdn.microsoft.com/en-us/library/vstudio/ms229060(v=vs.100).aspx

在我看来,你应该只在构造函数中放入初始化代码。

答案 4 :(得分:2)

使用BinaryFormatter反序列化对象时,创建对象时不会运行默认构造函数。 BinaryFormatter使用一种技巧来使.NET提供一个初始化实例,其中没有运行默认构造函数。

这不应该造成问题,因为BinaryFormatter会填充所有私有成员本身。我能想象的唯一危险的情况是,如果你使用默认构造函数在某个其他静态类中的某个地方“注册”对象,或者沿着这些行注册某些东西,在这种情况下,你会遇到一系列全新的问题。

答案 5 :(得分:2)

经验法则

尽可能简单。

良好编码标准的重点在于可维护性和调试能力。我们都遇到过意大利面条的代码。这只是让其他人更好地理解您的API。即使有良好的javadoc,大多数人也不会期望构造函数来更改应用程序状态。

例如,如果实例化你的对象做了一些数据库操作,你最好有一个很好的理由。

反例

你仍然需要做最好的事情。如果您决定使用延迟加载的单例来加载缓存或连接,或者您拥有什么,那么重点是它会在您实例化时自动加载某些内容。

答案 6 :(得分:0)

我知道我们调用了默认构造函数中所有参数的初始化。有些时候我们需要在声明之外“清空”数据,所以我们在一个单独的方法中进行,并在任何对象的最低构造函数中调用它。

答案 7 :(得分:0)

这是一个品味问题。我发现用户kokos定义的这些规则非常有用:

他的规则:

  
      
  1. 不要使用声明中的默认值进行初始化(null,false,0,0.0 ...)。
  2.   
  3. 如果您没有更改字段值的构造函数参数,则首选声明中的初始化。
  4.   
  5. 如果字段的值因构造函数参数而更改,则将初始化放在构造函数中。
  6.   
  7. 在练习中保持一致。 (最重要的规则)
  8.   

请参阅:Initialize class fields in constructor or at declaration?

答案 8 :(得分:0)

未初始化的类字段通常应该以默认构造函数结尾。如果在与声明相同的行上初始化类字段,则在反序列化此类对象时,这些语句将不会运行。此外,在默认的ctor中收集所有初始化是一种很好的做法。