为什么在构造函数中实例化新对象之前检查类变量是否为null?

Cod*_*ody 14 .net c# constructor

在我使用的前一个团队中,每当创建一个新的Service类来处理数据层和表示层之间的业务逻辑时,就会完成以下操作:

class DocumentService
{
    public DocumentRepository DocumentRepository { get; set; }

    public DocumentService()
    {
         if (DocumentRepository == null) DocumentRepository = new DocumentRepository();
    }
}
Run Code Online (Sandbox Code Playgroud)

我从来都不明白为什么检查是null在那里.如果正在调用构造函数,那意味着它必须为null ..因为它是一个新实例,对吧?

为什么要这样做?在我看来,这是一个多余的步骤,但我不想错过任何东西并将其作为不好的做法传递出去.

Hen*_*man 17

在这个确切的背景下:是的,这是多余的.

这个代码没有直接的原因,它可能是旧方法的遗留问题或者预期具有多个构造函数的实现.但我不建议使用这个'模式',甚至不保留这些代码.

  • @DoctorOreo:我建议如果你做了不必要的检查,你会考虑`Debug.Assert(DocumentRepository == null); DocumentRepository = new DocumentRepository();` - 如果检查确实*在某些您不知道的奇怪场景中是明智的,那么你很快就会知道它. (3认同)

Eri*_*ert 12

亨克的答案当然是正确的; 我只是想补充一点,我怀疑它来自何处.我敢打赌,在过去的某个时候有人写道:

class DocumentService
{
    private DocumentRespository documentRespository = null;
    public DocumentRepository DocumentRepository 
    { 
        get
        {
            if (documentRepository == null) 
                documentRepository = new DocumentRepository();
            return documentRepository;
        }
    }
    public DocumentService()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,该属性在首次使用时初始化.后来有人意识到这是错误的或不必要的,或者其他什么,并重写代码将构造放在构造函数中,使属性"渴望"而不是"懒惰",但忘记取出空检查.

如果人们通过从现有代码剪切和粘贴到新代码进行编程,则该模式可以传播.很快,一个神话就出现了,这就是它必须要做的事情.这就是为什么,我怀疑,这么多的Visual Basic程序员,你不得不说的错误信念Set Foo = Nothing,当你与富贵进行; 在某些情况下,这是必要的,现在人们即使在没有必要的情况下也会这样做,因为这就是我们在这里做的事情.

顺便说一下,你可能想说:

public DocumentRepository DocumentRepository { get; private set; } // note the private
Run Code Online (Sandbox Code Playgroud)

您希望服务的用户不太可能动态更改存储库.

  • @ Cyborgx37:*为什么总是将引用设置为null?*因为它使鳄鱼远离.*但西雅图没有短吻鳄.*看看它的效果如何? (9认同)
  • 当然,每隔一段时间,当我走出去排除这种愚蠢的绒毛时,"[工资单数据被删除](http://dilbert.com/strips/comic/2009-08-30/)". (2认同)

Den*_*aub 5

据我所知,你是绝对正确的.没有必要检查null.


Chr*_*ris 5

可能是覆盖了DocumentRepository的==运算符.

  • @DoctorOreo,http://msdn.microsoft.com/en-us/library/aa288467(v = vs.71).aspx (3认同)