7

在回答这个问题(https://stackoverflow.com/questions/352317/c-coding-question#352327)时,我想知道......

将静态类视为等效于实现单例模式的非静态类实例化是否有任何危险?

4

8 回答 8

10

唯一对我来说似乎很明显的是静态类基本上只是范围函数的集合(在这里明确避免“方法”),并且单例仍然是您可以实例化的东西,即使您只能有 1. 1 > 0。

您可以将单例作为参数传递给需要某个接口的对象的东西,您不能在任何地方传递静态类(除非通过一些反射技巧)

于 2008-12-09T10:47:11.240 回答
4

在许多方面,静态类和单例是相似的。一个很大的区别是单例可能会实现一些接口,而这对于静态类是不可能的。例如,Comparer<T>.Default/EqualityComparer<T>.Default提供(通过接口)在排序/字典使用中使用项目的能力。

也可以(虽然很棘手)将单例与标准序列化框架一起使用。使用静态类,您必须手动管理任何状态持久性。

于 2008-12-09T11:01:25.237 回答
2

它不完全等价。例如,您可以将对单例实例的引用作为参数传递,而静态类不能这样做,因为没有实例。

“危险”是什么意思?

于 2008-12-09T10:41:08.910 回答
1

正如罗伯特·古尔德(Robert Gould)指出的那样,您对建筑的控制权松了。您还会遇到更加晦涩难懂的施工问题。静态类很快就会以静态初始化块结束。这些块在有人第一次引用您的类型时被调用,而且这个顺序可能没有您想像的那样定义好。因此,这些静态初始化程序的运行顺序可能会在您没有计划的情况下发生变化,并且可能会导致奇怪的错误。

于 2008-12-09T10:51:20.857 回答
1

我可以看到静态类的主要危险是在编写单元测试时它们更难模拟。使用单例,您可以以这样的方式创建它,即您可以在其位置注入一个不同的类来测试特定的功能,而使用静态类则不是那么容易。

于 2008-12-09T11:38:22.120 回答
0

不确定 C#,但在 C++ 中,静态对象会在初始化时被初始化,并且您无法直接控制它(尤其是在多线程应用程序中)。所以你需要一个函数来调用你的对象,而不是直接调用它(除非你想要不可移植的代码)

于 2008-12-09T10:42:31.887 回答
0

正如罗伯特之前所说,初始化是静态类的主要缺点。静态类通常会在最后可能的时刻延迟初始化。但是,您失去了对确切行为的控制,并且静态构造函数很慢。

通常静态类用于保存全局数据。全局数据会在您的其他对象/类之间创建隐式依赖关系。所以在改变这个“全局对象”的时候一定要小心。可以破坏你的应用程序。

于 2008-12-09T10:52:43.973 回答
0

我认为,在单例实现的情况下,没有任何危险。我经常这样做,通过静态类实现单调。从逻辑上讲,如果对象引用是单独且唯一的,则它不是必需的。

于 2008-12-09T11:30:13.133 回答