C#中私有构造函数的作用是什么?

14
在 C# 中,私有构造函数的作用是什么?我在一次 C# 测试中看到了这个问题。
12个回答

32
例如,如果您有一个类应该只通过工厂方法创建。或者如果您有构造函数的重载,并且其中一些应该只被其他构造函数使用。可能还有其他原因 =)

2
实际上,当你需要控制类的实例化时,可以通过工厂模式或单例模式来实现。 - Andre Pena
@André:你的观点是什么?这仍然是使用私有构造函数的原因。除非你的工厂类是另一个类,但那是另一个话题。 - Svish

12

如果你了解一些设计模式,那就很明显:一个类可以在内部创建一个新的实例,不让其他人这样做。 以下是一个Java的例子(抱歉我不太熟悉C#)使用单例模式:

class Meh 
{
  private Meh() { }
  private static Meh theMeh = new Meh();
  public static Meh getInstance() { return theMeh; }
}

18
有趣的是,这段Java代码也可以作为C#代码运行——也许你比自己想象中更熟悉C#。 ;) - Erik Forbes

11

如果你想要防止类外部进行直接实例化,你需要使用私有构造函数(private constructor)。例如,在C# 2.0之前引入static类的情况下,你就需要使用私有构造函数来实现类似的功能:

sealed class StaticClass {
     private StaticClass() {
     }
     public static void DoSomething() {
     }
}

10

当你想要防止类的用户直接实例化该类时,可以使用以下方法。常见的情况包括:

  • 仅包含静态方法的类
  • 单例模式

7

我可以回忆起它的几个用途:

  • 您可以在同一类的静态工厂方法中使用它
  • 您可以在其中执行一些常见工作,然后从其他构造函数调用它
  • 您可以使用它来防止运行时自动添加空构造函数
  • 它可以被某些模拟和ORM工具(如nhibernate)使用(尽管是私有的)

2
私有构造函数用于防止在没有实例字段或方法(例如Math类)或调用方法以获得类的实例时创建类的实例。如果类中的所有方法都是静态的,请考虑使整个类为静态。有关更多信息,请参见静态类和静态类成员。
class NLog
{
    // Private Constructor:
    private NLog() { }

    public static double e = System.Math.E;  //2.71828...
}

下面是一个使用私有构造函数的类的示例。
public class Counter
{
    private Counter() { }
    public static int currentCount;
    public static int IncrementCount()
    {
        return ++currentCount;
    }
}

class TestCounter
{
    static void Main()
    {
        // If you uncomment the following statement, it will generate
        // an error because the constructor is inaccessible:
        // Counter aCounter = new Counter();   // Error

        Counter.currentCount = 100;
        Counter.IncrementCount();
        System.Console.WriteLine("New count: {0}", Counter.currentCount);
    }
}

2
例如,当您提供工厂方法来控制实例化时...
public class Test(){

  private Test(){
  }

  void DoSomething(){
    // instance method
  }

  public static Test CreateCoolTest(){
    return new Test();
  }
}

1

我虽然来得晚,但是阅读了所有其他答案后,我没有看到提到以下用法:

我在多个(公共的)构造函数中使用私有构造函数的情况下,并且它们都有一些共同的代码。通过构造函数链接,代码变得非常整洁和DRY。

请记住,私有只读变量只能在构造函数中设置,因此我不能使用普通方法。

例如:

public class MyClass
{
    private readonly int _a;
    private readonly int _b;
    private readonly string _x;

    public MyClass(int a, int b, string x)
        : this(x)
    {
        _a = a;
        _b = b;
    }

    public MyClass()
        : this("(not set)")
    {
        // Nothing set here...
    }

    private MyClass(string x)
    {
        _x = x;
    }
}

1
基本上,当您遵循单例设计模式时,使用私有构造函数。在这种情况下,您在类内定义了一个静态方法,该方法在内部调用私有构造函数。
因此,要第一次创建类的实例,用户调用classname.static_method_name。在此方法中,由于类的对象尚不存在,静态方法在内部调用私有构造函数并返回类的实例。
如果类的实例已经存在,则静态方法简单地将实例返回给调用方法。

1

虽然这个链接与Java有关,但我认为它应该能帮助你理解原因,因为这个想法基本上是相同的。

私有构造函数可以防止调用者显式实例化类。以下是一些常见情况,私有构造函数可能会有用:

  • 只包含静态实用方法的类
  • 只包含常量的类
  • 类型安全枚举
  • 单例模式

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接