C# – Valid Uses of Static Classes

cobject-orientedobject-oriented-design

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 using File 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 writeable Stream 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 a Math class was indeed called during a test?

On Programmer.SE, I've read:

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

what if; what if; what if?

YAGNI

Seriously. If someone wants to use different implementations of File or Math or Console 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.

Related Topic