I noticed that nearly every time I see programmers using static classes in object oriented languages such as C#, they are doing it wrong. The major problems are obviously the global state and the difficulty to swap implementations at runtime or with mocks/stubs during tests.
By curiosity, I've looked at a few of my projects selecting ones which are well tested and when I made an effort to actually think about architecture and design. The two usages of static classes I've found are:
The utility class—something I would rather avoid if I was writing this code today,
The application cache: using static class for that is plainly wrong. What if I want to replace it by
MemoryCache
or Redis?
Looking at .NET Framework, I don't see any example of a valid usage of static classes either. For example:
File
static class makes it really painful to switch to alternatives. For example, what if one needs to switch to Isolated Storage or store files directly in memory or needs a provider which can support NTFS transactions or at least be able to deal with paths longer than 259 characters? Having a common interface and multiple implementations appears as easy as usingFile
directly, with the benefit of not having to rewrite most of the code base when requirements change.Console
static class makes testing overly complicated. How should I ensure within a unit test that a method outputs a correct data to console? Should I modify the method to send the output to a writeableStream
which is injected at run time? Seems that a non-static console class would be as simple as a static one, just without all the drawbacks of a static class, once again.Math
static class is not a good candidate either; what if I need to switch to arbitrary precision arithmetic? Or to some newer, faster implementation? Or to a stub which will tell, during a unit test, that a given method of aMath
class was indeed called during a test?
On Programmer.SE, I've read:
Don't Use “Static” in C#? Some answers are quite against static classes. Others assert that “Static methods are fine to use and have a rightful place in programming.”, but don't bake it with arguments.
When to use a Singleton and when to use a static class. Utility classes are mentioned, given that I mentioned above that utility classes are problematic.
Why and when should I make a class 'static'? What is the purpose of 'static' keyword on classes? The only valid usage which is mentioned is a container for extension methods. Great.
Aside extension methods, what are the valid uses of static classes, i.e. cases where Dependency Injection or singletons are either impossible or will result in a lower quality design and harder extensibility and maintenance?
instanceof
) because given two instances ofIFoo
there's no guarantee they're backed by the same class.YAGNI
, and accept that if you ever need a different kind of string, you'll just get your IDE to change every instance ofcom.lang.lib.String
tocom.someones.elses.String
in the entire code base.