Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么选择静态类而不是单例实现?_C#_.net_Static_Singleton - Fatal编程技术网

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

C# 为什么选择静态类而不是单例实现?,c#,.net,static,singleton,C#,.net,Static,Singleton,静态与单一问题在SO中已经讨论过很多次。 然而,所有的答案都指出了单身的许多优点。 我的问题是-静态类比单例类有什么优势? 为什么不每次都选择一个单例呢?静态类是一种技术工具,基本上是一种语言特性 Singleton是一个架构概念 您可以使用静态类作为实现单例概念的手段。或者你可以使用其他的方法 对于C#中的静态类,如果不小心,有两个潜在的危险 在应用程序生命周期结束之前,不会释放请求的资源 静态变量的值在应用程序中共享。对于ASP.NET应用程序尤其糟糕,因为这些值将在驻留在特定应用程序域中

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

静态类是一种技术工具,基本上是一种语言特性

Singleton是一个架构概念

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

对于C#中的静态类,如果不小心,有两个潜在的危险

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

静态类和类成员用于创建数据和函数 无需创建类的实例即可访问。静止的 类成员可用于分离数据和行为,这是 独立于任何对象标识:数据和函数不会 无论对象发生什么情况,都要更改。静态类可以是 当类中没有依赖于的数据或行为时使用 对象标识

一个关键点是,静态类
不需要实例引用。还要注意,静态类是由语言和编译器专门启用的

单例类只是实现设计模式的用户编码类。Singleton的目的是
将类的实例化限制为单个实例

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

i、 e

将成为

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

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

除此之外,如果需要传递对实现特定接口的对象的引用,而“实现”应该是单例的,我认为单例是很好的,这是静态类所不能做到的。

我认为它们(通常)都是糟糕的解决方案。静态类有一些用例,主要是简单的实用程序类(想到C#3.0中的扩展方法)。然而,随着复杂性的增加,可测试性问题开始出现

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

所以你选择单身。你也有同样的问题——类A依赖于单例B。你不能孤立地测试类A

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


IoC()容器库是这个问题的一种解决方案;它们允许您将普通的旧类定义为具有较长的生命周期。当与模拟库结合使用时,它们可以使您的代码非常可测试。

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

GlobalSettings.SomeMethod();
那么从语法上讲,唯一可以通过
GlobalSettings
访问的就是您提供的成员。相反,如果
GlobalSettings
是一个实例(单例或其他),那么消费者可能会向
GlobalSettings
添加他们自己的扩展,否则他们将无法这样做:

application.GlobalSettings.CustomSomethingOrOther();


这是一个重复的问题。看不,这个问题与我的问题完全相反!请再次阅读这两个问题。考虑到您接受的答案实际上强调了使用静态类的潜在缺点,这是一个奇怪的回答。请参阅此。可能对你有用+1静态类和单例是全局可访问的。全球是邪恶的:-)
application.GlobalSettings.CustomSomethingOrOther();
GlobalSettings.Instance.CustomSomethingOrOther();