c#中的静态类

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

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

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

使用带有标准序列化框架的单例也是可能的(尽管很棘手)。 使用静态类,您必须手动管理任何状态持久性。

它并不完全等同。 例如,您可以将对单例实例的引用作为参数传递,但由于没有实例,因此无法对静态类进行引用。

“危险”是什么意思?

正如罗伯特古尔德指出的那样,你对建筑的控制权失控了。 您还将获得更加模糊的施工问题。 静态类很快就会出现静态初始化块。 这些块在第一次引用您的类型时被调用,并且此顺序可能没有您想要的那样定义。 因此,这些静态初始化程序的运行顺序可能会在您没有计划的情况下发生变化,并且可能导致奇怪的错误。

我可以在静态类中看到的主要危险是,在编写unit testing时,它们更难以模拟。 使用单例,您可以创建它,以便您可以在其测试特定function的位置注入不同的类,使用静态类这不是那么容易。

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

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

通常,静态类用于保存全局数据。 全局数据在您的其他对象/类之间创建隐式依赖关系。 因此,在更改此“全局对象”时,您必须保持谨慎。 可以打破你的申请。

在单身实施的背景下,我认为没有任何危险。 我经常这样做,通过静态类来改变单音。 从逻辑上讲,如果它是唯一且唯一的,则不需要对象引用。