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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1321352/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 15:07:28  来源:igfitidea点击:

Why choose a static class over a singleton implementation?

c#.netstaticsingleton

提问by Elad

The Static Vs. Singleton question has been discussed before many times in SO.
However, all the answers pointed out the many advantages of a singleton.
My question is - what are the advantages of a static class over a singleton? Why not simply choose a singleton every time?

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

回答by Elad

Static class is a technical tool in your box - basically a language feature.

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

Singleton is an architectural concept.

Singleton 是一个架构概念。

You may use a static class as a means to implement the singleton concept. Or you may use some other approach.

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

With static classes in C# there are two potentialdangers if you're not careful.

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

  • The requested resources will not be freed until the end of application life
  • The values of static variables are shared within an application. Especially bad for ASP.NET applications, because these values will then be shared between all users of a site residing in a particular Application Domain.
  • 请求的资源在应用程序生命周期结束之前不会被释放
  • 静态变量的值在应用程序享。对 ASP.NET 应用程序尤其不利,因为这些值将在驻留在特定应用程序域中的站点的所有用户之间共享。

回答by rism

From MSDN

来自MSDN

Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object. Static classes can be used when there is no data or behavior in the class that depends on object identity.

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

A key point is that static classes do not require an instance reference. Also note that static classes are specifically enabled by the language and compiler.

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

Singleton classes are just user coded classes implementing the Singletondesign pattern. Singleton purpose is to restrict instantiation of an class to a single instance.

单例类只是实现单例设计模式的用户编码类。Singleton 的目的是为了restrict instantiation of an class to a single instance.

If you coded every static class as a singleton you'd have to instantiate the class every time you used it.

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

i.e.

IE

Console.WriteLine('Hello World');

would become

会成为

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

回答by Cecil Has a Name

Static classes are much easier to implement - I have seen many attempts at thread-safe singletons in C# that employs naive locking schemes instead of depending on the run-time's guaranteed one-time initialization of static fields (optionally inside a nested class to delay instantiation).

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

Other than that, I think singletons are great if you need to pass around a reference to an object that implements a specific interface, when that 'implemention' should be singleton, something which you cannot do with static classes.

除此之外,我认为如果您需要传递对实现特定接口的对象的引用,当该“实现”应该是单例时,单例是很棒的,这是静态类无法做到的。

回答by TrueWill

I'd say they're both (generally) poor solutions. There are a few use cases for static classes, primarily simple utility ones (Extension Methods in C# 3.0 come to mind). With any degree of complexity, though, testability issues start cropping up.

我会说它们都是(通常)糟糕的解决方案。静态类有几个用例,主要是简单的实用程序(想到 C# 3.0 中的扩展方法)。然而,对于任何程度的复杂性,可测试性问题开始出现。

Say class A depends on static class B. You want to test class A in isolation. That's hard.

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

So you go with a Singleton. You have the same problem - class A depends on singleton B. You can't test class A in isolation.

所以你选择单身人士。你有同样的问题 - A 类依赖于单例 B。你不能单独测试 A 类。

When class B has other dependencies (such as hitting a database) or is mutable (other classes can change its global state), the problem is exacerbated.

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

IoC (Inversion of Control) container libraries are one solution to this problem; they let you define Plain Old Classes as having a long lifespan. When combined with a mocking library, they can make your code very testable.

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

回答by Kirk Woll

One consideration I don't see mentioned is that preferring a solution using an instance of a class (singletons, or their DI equivalent) allows you to provide a class on which other users of your code may define extension methods -- since extension methods only work with non-static classes as the thisparameter. In other words, if you have a line like:

我没有看到提到的一个考虑因素是,更喜欢使用类实例(单例或它们的 DI 等效项)的解决方案允许您提供一个类,您的代码的其他用户可以在该类上定义扩展方法——因为仅扩展方法使用非静态类作为this参数。换句话说,如果你有这样一行:

GlobalSettings.SomeMethod();

Then syntactically the only thing that can be accessed via GlobalSettingsare members you provide. In contrast, if GlobalSettingsis an instance (singleton or otherwise) then consumers may add their own extensions to GlobalSettingsthat they would be unable to do otherwise:

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

application.GlobalSettings.CustomSomethingOrOther();

or

或者

GlobalSettings.Instance.CustomSomethingOrOther();