空构造函数或无构造函数


67

我认为在类(C#)中具有默认构造函数不是强制性的。

因此,在那种情况下,我应该在类中有一个空的构造函数,还是可以跳过它?

有一个空的默认构造函数是最佳实践吗?

Class test
{
   public test()
   {

   }
        ......
}

要么

Class test
{
        ......
}

Answers:


77

如果该类不会被第三方使用,并且您不需要重载的构造函数,请不要编写空的构造函数。

但...

假设您已经发货了,而第三方使用了您的课程。几个月后,有一个新要求,使您添加带有参数的构造函数。

现在,通过这样做,C#编译器不再生成默认构造函数。如果未显式添加空的构造函数,则第三方代码将中断。

我认为,您应始终为第三方使用的公共类定义空的构造函数(一个衬里)。


4
在另一个主题上,如果要在COM程序中使用.NET类,则将需要一个公共的无参数构造函数-出于与Soe Moe解释的相同原因,我将其明确地放在类中。
Jean Hominal 2010年

10
您可能会争辩说,如果您要以此方式破坏第三方客户,您自己的单元测试应该会失败。
2013年

有时习惯性地使用某种模式来简化您的方法很好。这是我使用javascript分号的原因(因为我不想记住何时需要它们以及何时变得混乱)。但是,我认为在这种情况下,我将依靠单元测试来捕获错误,而不是将空的构造函数放在各处。我想个人喜好。无论如何,这个答案很棒,因为它揭示了为什么人们希望显式添加空构造函数的逻辑。
aaaaaa

尽管如此,当编译器生成默认构造函数时,仍然不需要编写默认构造函数。您将其用作一种预防措施,不要忘记在添加了另一个构造函数重载后再指定一次。当使用无参数构造函数被认为是受支持的用例时,应通过单元测试来确保它,而不是使用样板程序污染代码。
Palec

36

-如果您的类不需要在默认构造函数中做任何事情-则不要定义它。编译器将为您生成一个。

马口中

除非类是静态的,否则C#编译器会为没有构造函数的类提供一个公共的默认构造函数,以启用类实例化。


4
为了澄清:如果你的类确实有一个具有一个或多个参数的至少一个构造函数,那么C#编译器将不会为您创建一个默认的构造函数。在这种情况下,您可能想显式创建一个默认构造函数,即使它不做任何事情(即,它为空)。(有关更多信息,请参见接受的答案以及其他答案。)
DavidRR 2013年

10

There's nothing like default constructors。它是C#中的公共无参数构造函数。C#编译器将在编译时在类中寻找构造函数,如果未定义构造函数,则将添加一个公共的无参数构造函数。因此,如果您的类对象不需要任何特殊的构造操作,则可以跳过定义构造函数的操作。

其次,如果您定义一个带参数的构造函数,则编译器不会添加一个公共的无参数构造函数,因为编译器会假设您的对象必须通过您定义的构造函数进行构造。话虽如此,如果您至少有一个参数化的构造函数,并且需要用parameteress构造函数构造对象,则必须显式定义一个无参数的构造函数。

您还可以拥有一个私有的无参数构造函数,该构造函数有助于创建单例类。


5

如果不需要无参数的构造函数,请不要添加一个带有空主体的构造函数。但是,如果有人要序列化/反序列化类的对象,则需要无参数构造函数。

如果没有定义构造函数,那么编译器将自动为您生成一个默认的无参数构造函数,但是如果您自己定义一个构造函数则不会。

顺便说一句,您可以通过定义一个空的私有构造函数来禁止C#编译器自动生成的默认构造函数。


尽管序列化框架当然可以依赖于空的构造函数和可设置的属性,但这绝不是必需的。例如,Newtonsoft.Json允许您使用任何构造函数进行反序列化。您只需要用注释即可[JsonConstructor]
查尔斯·泰勒

4

默认情况下,C#将为您添加一个零参数构造函数。因此,如果您没有什么特别的事情,请不要添加。

如果您有另一个带有参数的构造函数并且想要保持无参数构造函数的生命,那么您将必须自己添加任何空的构造函数-即使没有代码也是如此。

您想添加一个空的无参数构造函数的另一种情况是,您想将其访问修饰符从public更改为其他属性(私有,受保护或内部)。


2

C#编译器将为您创建默认的构造函数,因此您不应使用空主体编写无参数的构造函数。


经验丰富的编码人员告诉我,如果没有它,将来
会给

2

我唯一要包括一个空的无参数构造函数的情况是,如果我希望该构造函数是私有的,或者希望无参数构造函数调用另一个以null为参数的重载。顺便说一句,在上面的示例中,您通过不指定public来使Test的构造函数私有。

class Foo
{
    public Foo()
        : this(null)
    {
    }

    public Foo(string bar)
    {
        if (bar != null)
        {
            Console.WriteLine(bar);
        }
    }
}

好的,我注意到的原因是因为私有构造函数对于强制类的用户使用您可能决定包含在类中的任何工厂方法很有用。例如,我的Foo类可以具有公共的静态Foo CreateFoo()工厂方法,而没有公共的构造函数……
Nate 2010年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.