简体   繁体   English

c#中的静态类

[英]Static classes in c#

In answering this question ( https://stackoverflow.com/questions/352317/c-coding-question#352327 ), it got me wondering... 在回答这个问题( https://stackoverflow.com/questions/352317/c-coding-question#352327 )时,它让我想知道......

Is there any danger in regarding a static class as being equivalent to a non-static class instatiation that implements the singleton pattern? 将静态类视为等效于实现单例模式的非静态类实例是否存在任何危险?

The only thing that seems immediately apparent to me is that a static class is basically just a collection of scoped functions (explicitly avoiding "methods" here) and a singleton is still something you can instantiate, even if you can only have 1. 1 > 0. 对我来说,唯一看起来很明显的是静态类基本上只是作用域函数的集合(这里明确地避免使用“方法”),单例仍然可以实例化,即使你只能有1个> 1> 0。

You can pass a singleton as an argument to something that expects an object of a certain interface, you cannot pass a static class anywhere (except through some reflection trickery) 您可以将单例作为参数传递给需要某个接口的对象的东西,您不能在任何地方传递静态类(除非通过一些反射技巧)

In many ways, a static class and a singleton are similar. 在许多方面,静态类和单例类似。 One big difference is that a singleton might implement some interfaces, which isn't possible with a static class. 一个很大的区别是单例可能会实现某些接口,这对于静态类是不可能的。 For example, Comparer<T>.Default / EqualityComparer<T>.Default provide (via the interface) the ability to use the item in sorting / dictionary usage. 例如, Comparer<T>.Default / EqualityComparer<T>.Default提供(通过接口)在排序/字典使用中使用该项的能力。

It is also possible (though tricky) to use a singleton with the standard serialization frameworks. 使用带有标准序列化框架的单例也是可能的(尽管很棘手)。 With a static class, you'd have to manage any state persistence manually. 使用静态类,您必须手动管理任何状态持久性。

It isn't exactly equivalent. 它并不完全等同。 For example you can pass a reference to a singleton instance as an argument, which you can't do with a static class as there isn't an instance. 例如,您可以将对单例实例的引用作为参数传递,但由于没有实例,因此无法对静态类进行引用。

What do you mean by "danger"? “危险”是什么意思?

As Robert Gould pointed out, you loose control over construction. 正如罗伯特古尔德指出的那样,你对建筑的控制权失控了。 You will also get construction issues which are a lot more obscure. 您还将获得更加模糊的施工问题。 Static classes quickly end up with static initializer blocks. 静态类很快就会以静态初始化程序块结束。 These blocks get called the first time someone references your type, and this order may not be as well defined as you like to think. 这些块在第一次有人引用您的类型时被调用,并且此顺序可能没有您想要的定义。 So the run-order of these static initializers may change without you planning so, and can cause strange bugs. 因此,这些静态初始化程序的运行顺序可能会在您没有计划的情况下发生变化,并且可能导致奇怪的错误。

The main danger that I can see with static classes is that they are much harder to mock when writing unit tests. 我可以在静态类中看到的主要危险是,在编写单元测试时,它们更难以模拟。 With a singleton you can create it in such a way that you can inject a different class in its place that does test specific functionality, with a static class this is not so easy. 使用单例,您可以创建它,以便您可以在其测试特定功能的位置注入不同的类,使用静态类这不是那么容易。

Not sure about C#, but in C++ a static Object will get initialized when it gets initialized, and you have no direct control over that (especially in multithreaded apps). 不确定C#,但在C ++中,静态Object在初始化时会被初始化,而你无法直接控制它(特别是在多线程应用程序中)。 So you need a function to call your object, not just call it directly (unless you want unportable code) 所以你需要一个函数来调用你的对象,而不是直接调用它(除非你想要不可移植的代码)

As Robert said before, the initialization is a main disadvantage of a static class. 正如罗伯特之前所说,初始化是静态类的主要缺点。 The static class will usually be initialized lazily, at the last possible moment. 静态类通常会在最后一刻延迟初始化。 However, you lose control over the exact behavior and static constructors are slow. 但是,您失去了对确切行为的控制,静态构造函数很慢。

Often static classes are used to hold global data. 通常,静态类用于保存全局数据。 And global data creates an implicit dependency between your other objects / classes. 全局数据在您的其他对象/类之间创建隐式依赖关系。 So you must be carful when changing this "global object". 因此,在更改此“全局对象”时,您必须保持谨慎。 Can break your application. 可以打破你的申请。

In context of singleton implementation there is no any danger, I think. 在单身实施的背景下,我认为没有任何危险。 I often do the same, imlementing singletone via static class. 我经常这样做,通过静态类来改变单音。 Logically, object reference isn't necessary if it's alone and unique. 从逻辑上讲,如果它是唯一且唯一的,则不需要对象引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM