【发布时间】:2009-05-28 09:46:57
【问题描述】:
C#中的私有构造函数有什么需要? 我把它作为 C# 测试的问题。
【问题讨论】:
标签: c#
C#中的私有构造函数有什么需要? 我把它作为 C# 测试的问题。
【问题讨论】:
标签: c#
例如,如果您有一个只能通过工厂方法创建的类。或者,如果您有构造函数的重载,并且其中一些只能由其他构造函数使用。可能还有其他原因 =)
【讨论】:
如果你知道一些设计模式,那很明显:一个类可以在内部创建一个自己的新实例,而不是让其他人这样做。 一个带有单例类的 Java 示例(我不太了解 C#,抱歉):
class Meh
{
private Meh() { }
private static Meh theMeh = new Meh();
public static Meh getInstance() { return theMeh; }
}
【讨论】:
当您想阻止从外部直接实例化一个类时,您将使用private 构造函数。例如,在引入 static 类的 C# 2.0 之前,您使用 private 构造函数来完成大致相同的事情:
sealed class StaticClass {
private StaticClass() {
}
public static void DoSomething() {
}
}
【讨论】:
当您想阻止您的类的用户直接实例化该类时。一些常见的情况是:
【讨论】:
我能回忆起它的一些用法:
【讨论】:
例如,当您提供工厂方法来控制实例化时...
public class Test(){
private Test(){
}
void DoSomething(){
// instance method
}
public static Test CreateCoolTest(){
return new Test();
}
}
【讨论】:
在没有实例字段或方法(例如 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);
}
}
【讨论】:
虽然this link is related to java,但我认为它应该可以帮助您理解原因,因为这个想法几乎相同。
私有构造函数防止类被调用者显式实例化。在一些常见的情况下,私有构造函数很有用:
- 仅包含静态实用方法的类
- 只包含常量的类
- 类型安全枚举
- 单身人士
【讨论】:
如果基类的构造函数的参数与子类构造函数的参数类型不同,但您仍然需要子类中基类的功能,例如,您可以将其与继承一起使用。受保护的方法。
一般情况下,应尽可能避免这种情况,因为这是一种不好的继承形式。
【讨论】:
我迟到了,但阅读所有其他答案,我没有看到提到这种用法:
在我有多个(公共)构造函数的情况下,我使用私有构造函数,并且它们都有一些共同的代码。使用构造函数链接,代码变得非常整洁和干燥。
记住,私有只读变量只能在构造函数中设置,所以我不能使用常规方法。
例子:
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;
}
}
【讨论】:
基本上,当您遵循单例设计模式时,您会使用私有构造函数。在这种情况下,您在内部调用私有构造函数的类中定义了一个静态方法。
所以第一次创建类的实例,用户调用classname.static_method_name。在这个方法中,由于类的对象还不存在,静态方法内部调用私有构造函数并返回类的实例。
如果类的实例已经存在,那么静态方法简单地将实例返回给调用方法。
【讨论】:
当然,您可以使用私有构造函数来防止子类化。
【讨论】: