【问题标题】:Differences between static class and instance class with private constructor带私有构造函数的静态类和实例类的区别
【发布时间】:2010-04-01 20:50:25
【问题描述】:

虽然静态类只有一个实例,不能实例化,但是有私有构造函数的类是不能实例化的(因为看不到构造函数),所以每次调用这个类的时候,都是这样同一个实例?

工厂类总是遵循最后一个约定(带有私有构造函数的实例类)。这是为什么呢?

谢谢

【问题讨论】:

  • 实际上你可以在不调用构造函数的情况下创建一个实例。见msdn.microsoft.com/en-us/library/…
  • 专业提示:这里永远不需要programming 标签。任何不符合“编程”条件的问题通常都会被关闭,从而使标签变得不必要和多余。

标签: c#


【解决方案1】:

没有什么可以阻止具有私有构造函数的类拥有一个返回类实例的公共静态方法:

public class NoPublicConstructor
{
    private NoPublicConstructor()
    {
    }

    public static NoPublicConstructor NewInstance()
    {
        return new NoPublicConstructor();
    }
}

如您所见,静态方法不会返回相同的一个实例。

编辑: 工厂类这样做的原因之一是能够在未来的版本中分离责任:虽然您的代码总是调用工厂创建方法,但作者可能会移动所有“胆量”从那个类中移出另一个类,您的代码不需要知道其中的区别。调用该类的(公共)构造函数在一定程度上将其与原始类实现联系起来。

【讨论】:

  • 我有点想知道和提问者一样的事情,为什么不拿你的例子把它改成“public static class NoPublicConstructor”呢?有什么不同?我猜这可能与可测试性和在进行单元测试时使用模拟工厂的能力有关。
  • @AaronLS,Jesse 的重点不是您应该 做什么,而是展示了静态类和没有公共构造函数的类之间的区别。关键是您仍然可以获得后一个类的实例。您是否希望某人能够做到这一点是一种设计选择。
  • @Anthony:现场。肯定有一个相当大的代码库,它也使用两者的组合作为延迟实例化的单例。虽然这可以通过嵌入一个子类的纯静态类来实现(Jon Skeet 有一篇很棒的文章,虽然我不记得链接了),但从 Java 移植的 .NET 代码的一个很好的帮助遵循私有构造函数、公共实例访问器单例对象模型。
  • 虽然您的代码总是调用工厂创建方法,但作者可能会将所有“胆量”从该类移到不同的类中,您的代码不需要知道其中的区别——这将如何工作?被调用者的代码还需要更新吗?谢谢。
【解决方案2】:

您不能*从类外部获取实例,但可以从内部获取。静态方法或内部类可以使用私有构造函数创建并返回该类的实例。静态类不能被任何东西实例化。

class Foo
{
    private Foo()
    {
    }

    public class Bar
    {
        public Bar()
        {
        }

        public Foo GetFoo()
        {
            return new Foo();
        }
    }
}

..

Foo.Bar fooBar = new Foo.Bar();
Foo foo = fooBar.GetFoo();

编辑: *我使用“不能”这个词是松散的。 Brian Rasmussen 在 OP 的 cmets 中指出,获取实例的另一种方法是通过 System.Runtime.Serialization.FormatterServices 调用,这是类本身的外部。

Foo foo = (Foo)System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject(typeof(Foo));

【讨论】:

    【解决方案3】:

    使用私有构造函数创建类是实现“单例”对象的常见模式。

    Singleton 通常会实例化自己的一个实例,并且只允许通过静态“Instance”属性访问它,这意味着该类只有一个实例。

    与纯静态类相比,使用单例的优势在于您可以在单例中使用接口和不同的实现类。您的“单例”可能会为一组方法公开一个接口,您可以选择在幕后实例化哪个确切的实现类。如果您使用的是纯静态类,则很难在不影响其他代码的情况下换出完全不同的实现。

    Singleton 的主要缺点是很难更换实现类进行测试,因为它是在 Singleton 私有方法中控制的,但有一些方法可以解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-12
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      相关资源
      最近更新 更多