静态构造函数和私有构造函数有何不同?

时间:2013-03-27 14:52:09

标签: c# .net visual-studio-2010

静态构造函数和私有构造函数有何不同?

public class WorkstationDevicePresenter
{
    private WorkstationDevicePresenter()
    {}
} 

将它们留空是什么意思?

4 个答案:

答案 0 :(得分:17)

  

将他们留空的重点是什么?

制作“空白”构造函数有很多原因。

您可能会创建一个空白构造函数,因为您希望在调试期间设置一个断点。

您可能会创建一个空白的静态构造函数,因为这样做会更改静态字段初始值设定项的语义。请阅读Jon's article on the subject了解详情。

让我们留下静态构造函数并考虑空白实例构造函数。

激励空白构造函数的关键规则是:默认情况下,如果类型中没有构造函数,则可以免费获得“空白”无参数公共构造函数。如果某个类型中有任何构造函数,那么您就不会免费获得空白的无参数公共构造函数。

所以你想要一个空白构造函数的第一个显而易见的原因是:我想要一个空白的无参数构造函数,但我已经创建了另一个ctor,所以我不再免费获得一个。

第二个原因是你没有任何ctors,你不想要一个空的无参数 public 构造函数。您可能需要一个空的无参数私有,内部或受保护的构造函数。如果那就是你想要的那么你就必须自己制作一个。

特别是,将一个空的私有ctor作为唯一的ctor意味着该类不能通过类外部的构造函数进行实例化。如果要使用工厂模式,这非常有用。它还可以防止类外部的代码生成派生类,因为派生类必须能够调用构造函数。如果所有构造函数都是私有的,那么它们就无法派生。

我经常在工厂模式上使用这种变体:

public abstract class Thing
{
  private Thing() {}
  private class RedThing : Thing { ... }
  public static Thing GetRedThing() { return new RedThing(); }
}

通过创建一个私有构造函数,我可以创建一个公共抽象类,只能通过我的代码进行实例化,并且只能通过我的代码进行扩展,因此我有一个不错的不变量:每当我看到Thing类型的对象时,我都知道它来自哪里。

答案 1 :(得分:2)

静态构造函数在加载类时发生一次,私有构造函数在通常用于创建单例的一些公共静态方法或使用Builder模式调用时发生。没有理由拥有一个空白的私有构造函数(我知道)。

答案 2 :(得分:1)

静态构造函数初始化类的静态部分,私有构造函数只能由类本身使用,比如创建类的单例对象。

public class MyClass {

    private static int staticitem;
    private int instanceitem;

    static MyClass(){
        staticitem = 0; //define value for staticitem
    }

    private MyClass() { //can only be called from within the class
       instanceitem = 0; //define value for instanceitem
    }

    public static MyClass GetMyClass() {
       MyClass m = new MyClass();
       return m;
    }    

}

答案 3 :(得分:1)

空白私有构造函数将使该类不受其他任何东西的影响。如果您没有这段代码,默认情况下,编译器会创建一个空白的 public 无参数构造函数。

在创建静态实例时调用静态构造函数。

例如,您可以使用它们来创建Singleton模式。

检查以下代码:

public class Singleton
{
    public static Singleton Instance;
    static Singleton
    {
        Instance = new Singleton();
    }
    private Singleton()
    {
    }
}

public class SomeOtherClass
{
    public static Singleton CompileError = new Singleton();
    public static Singleton CompileOK = Singleton.Instance;
}