为什么选择静态类而不是单例实现?

时间:2009-08-24 09:30:04

标签: c# .net static singleton

静态VS.在SO中已经多次讨论过单身人士问题 然而,所有的答案都指出了单身人士的许多优点。 我的问题是 - 静态类比单例有什么优势? 为什么不每次只选择一个单身?

5 个答案:

答案 0 :(得分:40)

静态类是您框中的技术工具 - 基本上是一种语言功能。

Singleton是一种建筑概念。

您可以使用静态类作为实现单例概念的方法。或者您可以使用其他方法。

如果您不小心,使用C#中的静态类会有两个潜在的危险。

  • 在应用程序生命周期结束之前,将不会释放请求的资源
  • 静态变量的值在应用程序中共享。对于ASP.NET应用程序尤其糟糕,因为这些值将在驻留在特定应用程序域中的站点的所有用户之间共享。

答案 1 :(得分:23)

来自MSDN

  

静态类和类成员用于创建数据和函数   无需创建类的实例即可访问。静态的   类成员可用于分隔数据和行为   独立于任何对象标识:数据和功能不相关   无论对象发生什么变化都会发生变化。静态类可以   当依赖于类中没有数据或行为时使用   对象身份。

关键是静态类do not require an instance reference。另请注意,语言和编译器专门启用了静态类。

Singleton类只是实现Singleton设计模式的用户编码类。单身人士的目的是restrict instantiation of an class to a single instance

如果您将每个静态类编码为单例,则每次使用它时都必须实例化该类。

即。

Console.WriteLine('Hello World');

会变成

Console c = Console.getInstance();
c.WriteLine('Hello World');

答案 2 :(得分:9)

我会说他们(通常)都是糟糕的解决方案。静态类有一些用例,主要是简单实用的(C#3.0中的扩展方法)。但是,随着任何程度的复杂性,可测试性问题开始出现。

假设A类依赖于静态类B.您希望单独测试A类。那很难。

所以你选择了Singleton。你有同样的问题 - A类依赖于单身B.你不能孤立地测试A类。

当B类具有其他依赖关系(例如命中数据库)或者是可变的(其他类可以改变其全局状态)时,问题会更加严重。

IoC(Inversion of Control)容器库是解决此问题的一种方法;它们允许您将Plain Old Classes定义为具有较长的使用寿命。当与模拟库结合使用时,它们可以使您的代码非常可测试。

答案 3 :(得分:6)

静态类更容易实现 - 我已经看到C#中的线程安全单例的许多尝试采用了朴素锁定方案,而不是依赖于运行时保证静态字段的一次性初始化(可选地在嵌套类中)延迟实例化。)

除此之外,我认为如果你需要传递对实现特定接口的对象的引用,那么单例是很好的,当'实现'应该是单例时,你不能用静态类做什么。

答案 4 :(得分:2)

我没有提到的一个考虑因素是,更喜欢使用类实例(单例或其DI等价物)的解决方案允许您提供一个类,代码的其他用户可以在其中定义扩展方法 - 因为扩展方法仅适用于非静态类作为this参数。换句话说,如果您有一行:

GlobalSettings.SomeMethod();

然后在语法上,唯一可以通过GlobalSettings访问的是你提供的成员。相反,如果GlobalSettings是一个实例(单身或其他),那么消费者可以将他们自己的扩展添加到GlobalSettings,否则他们将无法做到:

application.GlobalSettings.CustomSomethingOrOther();

GlobalSettings.Instance.CustomSomethingOrOther();