C# 静态类和带有私有构造函数的实例类之间的差异
虽然一个静态类只有一个实例并且不能被实例化,但是一个具有私有构造函数的类不能被实例化(因为构造函数不能被看到),所以每次调用这个类时,这个实例都是相同的 工厂类始终遵循最后一个约定(带有私有构造函数的实例类)。为什么会这样C# 静态类和带有私有构造函数的实例类之间的差异,c#,C#,虽然一个静态类只有一个实例并且不能被实例化,但是一个具有私有构造函数的类不能被实例化(因为构造函数不能被看到),所以每次调用这个类时,这个实例都是相同的 工厂类始终遵循最后一个约定(带有私有构造函数的实例类)。为什么会这样 谢谢没有任何东西可以阻止使用私有构造函数的类使用公共静态方法返回类的实例: public class NoPublicConstructor { private NoPublicConstructor() { } public static
谢谢没有任何东西可以阻止使用私有构造函数的类使用公共静态方法返回类的实例:
public class NoPublicConstructor
{
private NoPublicConstructor()
{
}
public static NoPublicConstructor NewInstance()
{
return new NoPublicConstructor();
}
}
如您所见,静态方法不会返回同一个实例
编辑:工厂类这样做的原因之一是能够在将来的版本中分离责任:虽然您的代码总是调用工厂创建方法,但作者可能会将该类中的所有“胆量”移到另一个类中,而您的代码不需要知道它们之间的区别。调用该类(public)构造函数将其与原始类实现绑定在一定程度上。您不能*从类外部获取实例,但可以从类内部获取实例。静态方法或内部类可以使用私有构造函数创建并返回类的实例。静态类不能被任何对象实例化
class Foo
{
private Foo()
{
}
public class Bar
{
public Bar()
{
}
public Foo GetFoo()
{
return new Foo();
}
}
}
编辑:*我松散地使用“不能”一词。Brian Rasmussen在对OP的评论中指出,获取实例的另一种方法是通过System.Runtime.Serialization.FormatterServices调用,这是类本身的外部方法
Foo foo = (Foo)System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject(typeof(Foo));
使用私有构造函数创建类是实现“Singleton”对象的常见模式 Singleton通常会实例化自身的一个实例,并且只允许通过静态“instance”属性访问它,这意味着该类只有一个实例 与纯静态类相比,使用单例的优势在于可以在单例中利用接口和不同的实现类。您的“单例”可能会公开一组方法的接口,您可以选择在封面下实例化哪个确切的实现类。如果您使用的是纯静态类,则很难在不影响其他代码的情况下交换出完全不同的实现
Singleton的主要缺点是很难替换实现类进行测试,因为它是在Singleton私有方法中控制的,但是有一些方法可以绕过它。实际上,您可以创建一个实例,而无需调用构造函数。请参阅专业提示:这里不需要
编程
标记。任何不符合“编程”条件的问题通常都是封闭的,这使得标记变得不必要和多余。我有点想知道与发问者一样的事情,为什么不以您的例子将其更改为“public static class nopublic构造函数”?有什么区别?我猜这可能与可测试性和在进行单元测试时使用模拟工厂的能力有关。@AaronLS,Jesse的重点不是你应该做什么,而是演示静态类和没有公共构造函数的类之间的区别。关键是,您仍然可以获得后一个类的实例。你是否希望有人能做到这一点是一个设计上的选择。@Anthony:没错。当然,有一个相当大的代码库,它也将这两个代码库的组合用作延迟实例化的单例。虽然这可以通过嵌入子类的纯静态类实现(Jon Skeet有一篇很棒的文章,尽管我记不起链接),但是从Java移植的.NET代码的一个很好的帮助遵循了单例对象模型的私有构造函数、公共实例访问器,作者可能会将所有“胆量”从该类移到另一个类中,而您的代码不需要知道它们之间的区别——这是如何工作的?被调用方的代码仍需要更新?谢谢
Foo foo = (Foo)System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject(typeof(Foo));