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?
Best Answer
YAGNI
Seriously. If someone wants to use different implementations of
File
orMath
orConsole
then they can go through the pain of abstracting that away. Have you seen/used Java?!? The Java standard libraries are a fine example of what happens when you abstract things for the sake of abstraction. Do I really need to go through 3 steps to build my Calendar object?All that said, I'm not going to sit here and defend static classes strongly. Static state is solidly evil (even if I still use it occasionally to pool/cache things). Static functions can be evil due to concurrency and testability issues.
But pure static functions are not that terrible. There are elementary things that don't make sense to abstract out since there's no sane alternative for the operation. There are implementations of a strategy that can be static because they're already abstracted via the delegate/functor. And sometimes these functions don't have an instance class to be associated with, so static classes are fine to help organize them.
Also, extension methods are a practical use, even if they're not philosophically static classes.