When to use static classes in C#

497,219

Solution 1

I wrote my thoughts of static classes in an earlier Stack Overflow answer: Class with single method -- best approach?

I used to love utility classes filled up with static methods. They made a great consolidation of helper methods that would otherwise lie around causing redundancy and maintenance hell. They're very easy to use, no instantiation, no disposal, just fire'n'forget. I guess this was my first unwitting attempt at creating a service-oriented architecture - lots of stateless services that just did their job and nothing else. As a system grows however, dragons be coming.

Polymorphism

Say we have the method UtilityClass.SomeMethod that happily buzzes along. Suddenly we need to change the functionality slightly. Most of the functionality is the same, but we have to change a couple of parts nonetheless. Had it not been a static method, we could make a derivate class and change the method contents as needed. As it's a static method, we can't. Sure, if we just need to add functionality either before or after the old method, we can create a new class and call the old one inside of it - but that's just gross.

Interface woes

Static methods cannot be defined through interfaces for logic reasons. And since we can't override static methods, static classes are useless when we need to pass them around by their interface. This renders us unable to use static classes as part of a strategy pattern. We might patch some issues up by passing delegates instead of interfaces.

Testing

This basically goes hand in hand with the interface woes mentioned above. As our ability of interchanging implementations is very limited, we'll also have trouble replacing production code with test code. Again, we can wrap them up, but it'll require us to change large parts of our code just to be able to accept wrappers instead of the actual objects.

Fosters blobs

As static methods are usually used as utility methods and utility methods usually will have different purposes, we'll quickly end up with a large class filled up with non-coherent functionality - ideally, each class should have a single purpose within the system. I'd much rather have a five times the classes as long as their purposes are well defined.

Parameter creep

To begin with, that little cute and innocent static method might take a single parameter. As functionality grows, a couple of new parameters are added. Soon further parameters are added that are optional, so we create overloads of the method (or just add default values, in languages that support them). Before long, we have a method that takes 10 parameters. Only the first three are really required, parameters 4-7 are optional. But if parameter 6 is specified, 7-9 are required to be filled in as well... Had we created a class with the single purpose of doing what this static method did, we could solve this by taking in the required parameters in the constructor, and allowing the user to set optional values through properties, or methods to set multiple interdependent values at the same time. Also, if a method has grown to this amount of complexity, it most likely needs to be in its own class anyway.

Demanding consumers to create an instance of classes for no reason

One of the most common arguments is: Why demand that consumers of our class create an instance for invoking this single method, while having no use for the instance afterwards? Creating an instance of a class is a very very cheap operation in most languages, so speed is not an issue. Adding an extra line of code to the consumer is a low cost for laying the foundation of a much more maintainable solution in the future. And finally, if you want to avoid creating instances, simply create a singleton wrapper of your class that allows for easy reuse - although this does make the requirement that your class is stateless. If it's not stateless, you can still create static wrapper methods that handle everything, while still giving you all the benefits in the long run. Finally, you could also make a class that hides the instantiation as if it was a singleton: MyWrapper.Instance is a property that just returns new MyClass();

Only a Sith deals in absolutes

Of course, there are exceptions to my dislike of static methods. True utility classes that do not pose any risk to bloat are excellent cases for static methods - System.Convert as an example. If your project is a one-off with no requirements for future maintenance, the overall architecture really isn't very important - static or non static, doesn't really matter - development speed does, however.

Standards, standards, standards!

Using instance methods does not inhibit you from also using static methods, and vice versa. As long as there's reasoning behind the differentiation and it's standardised. There's nothing worse than looking over a business layer sprawling with different implementation methods.

Solution 2

When deciding whether to make a class static or non-static you need to look at what information you are trying to represent. This entails a more 'bottom-up' style of programming where you focus on the data you are representing first. Is the class you are writing a real-world object like a rock, or a chair? These things are physical and have physical attributes such as color, weight which tells you that you may want to instantiate multiple objects with different properties. I may want a black chair AND a red chair at the same time. If you ever need two configurations at the same time then you instantly know you will want to instantiate it as an object so each object can be unique and exist at the same time.

On the other end, static functions tend to lend more to actions which do not belong to a real-world object or an object that you can easily represent. Remember that C#'s predecessors are C++ and C where you can just define global functions that do not exist in a class. This lends more to 'top-down' programming. Static methods can be used for these cases where it doesn't make sense that an 'object' performs the task. By forcing you to use classes this just makes it easier to group related functionality which helps you create more maintainable code.

Most classes can be represented by either static or non-static, but when you are in doubt just go back to your OOP roots and try to think about what you are representing. Is this an object that is performing an action (a car that can speed up, slow down, turn) or something more abstract (like displaying output).

Get in touch with your inner OOP and you can never go wrong!

Solution 3

For C# 3.0, extension methods may only exist in top-level static classes.

Solution 4

If you use code analysis tools (e.g. FxCop), it will recommend that you mark a method static if that method don't access instance data. The rationale is that there is a performance gain. MSDN: CA1822 - Mark members as static.

It is more of a guideline than a rule, really...

Solution 5

I do tend to use static classes for factories. For example, this is the logging class in one of my projects:

public static class Log
{
   private static readonly ILoggerFactory _loggerFactory =
      IoC.Resolve<ILoggerFactory>();

   public static ILogger For<T>(T instance)
   {
      return For(typeof(T));
   }

   public static ILogger For(Type type)
   {
      return _loggerFactory.GetLoggerFor(type);
   }
}

You might have even noticed that IoC is called with a static accessor. Most of the time for me, if you can call static methods on a class, that's all you can do so I mark the class as static for extra clarity.

Share:
497,219
pbh101
Author by

pbh101

Software developer at IMC Financial Markets. Primarily work in Java and Bash, with Python and C++ distant seconds.

Updated on February 22, 2020

Comments

  • pbh101
    pbh101 over 4 years

    Here's what MSDN has to say under When to Use Static Classes:

    static class CompanyInfo
    {
        public static string GetCompanyName() { return "CompanyName"; }
        public static string GetCompanyAddress() { return "CompanyAddress"; }
        //...
    }
    

    Use a static class as a unit of organization for methods not associated with particular objects. Also, a static class can make your implementation simpler and faster because you do not have to create an object in order to call its methods. It is useful to organize the methods inside the class in a meaningful way, such as the methods of the Math class in the System namespace.

    To me, that example doesn't seem to cover very many possible usage scenarios for static classes. In the past I've used static classes for stateless suites of related functions, but that's about it. So, under what circumstances should (and shouldn't) a class be declared static?

  • Mark S. Rasmussen
    Mark S. Rasmussen over 15 years
    I'd rather not use extension methods for helper methods. Extension methods are messy, confusing for other developers and not generally intuitive across other languages. Extension methods have their purpose, but not as generic helper methods imho.
  • jonnii
    jonnii over 15 years
    Just to clarify, by helper method I mean something like: string.ToSentence(), or string.Camelize(). Essentially anything that would live in a class like StringHelpers.
  • chakrit
    chakrit over 15 years
    Steve Yegge has written about it as well. But his post is wayyy longer than could be post here. If you're still not convinced, try steve.yegge.googlepages.com/singleton-considered-stupid
  • John Kraft
    John Kraft over 15 years
    Has anyone ever noticed that the statement, "Only a Sith deals in absolutes," is an absolute? Sorry. Couldn't help it.
  • Jason Bunting
    Jason Bunting over 15 years
    Extension methods put you on a slippery slope...I think if you find yourself adding more than 2 extension methods for a given type, it might be time to examine why.
  • Mark S. Rasmussen
    Mark S. Rasmussen over 15 years
    Those two examples, I would especially not like. The more generic the type, the less suitable it is for extension methods. The worst example is beginning to add ToInt32() method to Object, ToDateTime() etc. I'd much rather have these in separate classes.
  • Mark S. Rasmussen
    Mark S. Rasmussen over 15 years
    Just as I go out on a limb to get my point across, so does Yegge. Some of his points comes down to normal programming consideration - if the singleton keeps valuable resources open, that may be a problem, of course. Given careful consideration, there are places for singletons and statics alike.
  • NotMe
    NotMe over 13 years
    @John Kraft: That was obviously written by a Sith.
  • Mark S. Rasmussen
    Mark S. Rasmussen almost 13 years
    @Rob I must say I don't believe what I wrote to be that subjective. Sure, this is my opinion, but many of the pitfalls and problems I mention are not subjective, they're pitfalls that typically arise from overusing static classes - and only knowing about them will help you avoid them. I'm not saying you should never use them - please read my into, "Only a Sith deals in absolutes" and the "Standards, standards, standards!" sections again - in all those three I argue that using statics is OK, as long as you know what you're doing.
  • Rob
    Rob almost 13 years
    @Mark Sorry, you're right (I've pulled that comment as it was a bit off topic), your points are very well made and I agree with most of it. I was talking more about whether people like to use them, and the feeling programmers generally get about using them. I've heard people actually say "they just don't smell right" :). The subjective quote was really related to this.
  • Rob
    Rob almost 13 years
    @Mark The path you pick as a dev who knows the pros/cons is often very subjective. Very rarely do we only have one way to code something. I personally really like the freedom of knowing that from anywhere StaticClassX is available. It's a trade-off I often make in certain projects. Usually single apps, which themselves have very low re-usability.
  • Rob
    Rob almost 13 years
    @Mark PS. I realise I could use a singleton pattern, and often do. Statics are just cleaner for certain narrow use cases. IMHO. :)
  • Mark S. Rasmussen
    Mark S. Rasmussen almost 13 years
    I agree, I use statics myself too. In contrast to earlier, I just consider my reasoning before doing so, now :)
  • Kirk Woll
    Kirk Woll over 11 years
    The answer saying "there can be only one" is not talking about the number of static classes, but rather cutely (though rather incorrectly) alluding to the fact that there can only be one instance (wrong, because actually there can only be zero instances)
  • Admin
    Admin over 11 years
    Ah thanks Kirk, hence my confusion; in any case simply dismissing static or blanketly stating that the singleton pattern is better (as I have seen) is in my opinion taking a very valuable tool out of the toolbox.
  • BRogers
    BRogers over 11 years
    I've used static methods to often on one application and now I feel like my code isn't as beautiful as it once was. I basically sacrificed beauty for speed of development. Thanks for posting, you've led me into doing some more research.
  • John ClearZ
    John ClearZ over 10 years
    Why do you define an unused parameter in the generic method?
  • Jogi Joseph George
    Jogi Joseph George about 10 years
    @Mark... Under heading "Parameter Creep", you told that, "But if parameter 6 is specified, 7-9 are required to be filled in as well". Why can't you use named parameters?
  • Mark S. Rasmussen
    Mark S. Rasmussen about 10 years
    @JogiJosephGeorge When I wrote this post back in 2008, optional/named parameters did not exist. They're not a perfect solution though as they have their own problems, especially if you intend your code to be used as a library for other developers to implement. As such, if we're prioritizing clean code, testability, usability, etc. I'd not recommend using them. Just like statics, there are lots of practical cases where I'd use them, but in general, I prefer to avoid them.
  • Philipp M
    Philipp M almost 10 years
    @JohnClearZ maybe because then you can call For with an existing object and you get the logger for it without thinking about the actual type of the object. Just a guess.
  • Zack
    Zack about 9 years
    You are just describing what a static class is, instead of describing when they would be practical, or what their purpose is.
  • Colin
    Colin over 8 years
    Regarding your point about disregarding keeping code clean (because pointless instantiation is ugly, and an "Instance" property has singleton implications and adds clutter besides), I think there's a happy middle that both keeps code clean AND allows for abstraction; have a static method that performs the operation, but create an actual instance from within the static method. From the perspective of the caller, they see only "CleanCode.Do()" (or "CleanCode<InstanceType>.Do()" if you need flexibility), but you're getting all the benefits you mentioned behind-the-scenes.
  • frostymarvelous
    frostymarvelous about 8 years
    Aren't singletons the devil's spawn too? Aren't we supposed to use IoC/DI?
  • Chef_Code
    Chef_Code almost 8 years
    “You must be shapeless, formless, like water. When you pour water in a cup, it becomes the cup. When you pour water in a bottle, it becomes the bottle. When you pour water in a teapot, it becomes the teapot. Water can drip and it can crash. Become like water my friend.” - Bruce Lee
  • Jogi
    Jogi almost 8 years
    @Chef_Code I'm sorry I couldn't understand - how is your quote relevant to given question if you don't mind me asking?
  • Mehdi Dehghani
    Mehdi Dehghani over 7 years
    @MarkS.Rasmussen great answer, but would you please tell me there is no RAM issue of using static classes? I mean if we use static class the application use more RAM than non-static class?
  • user2802557
    user2802557 over 7 years
    You can create in classes in C++, pretty much the same as C#, that is the main difference between C++ and C.
  • Admin
    Admin about 7 years
    GREAT explanation - best one I've seen for this in terms of simplicity and conciseness. I would recommend this one plus Mark Rasmussen's for more detail, to anyone on this topic!
  • camelCase
    camelCase almost 7 years
    In addition such a static declaration on a private method in an instance class conveys useful additional info to a developer. It informs that a such private static method does not change instance state .i.e. the method is a utility method within a class.
  • niico
    niico over 6 years
    His question was 'when to USE static classes' - but you appear to have answered the question 'when NOT to use static classes' - subtle. But I'm still none the wise as to when you SHOULD be using them. A few examples of appropriate use would be good + what if two threads call a static class or method very close together - when is that good / bad?
  • Bloopy
    Bloopy over 6 years
    "There can be only one" is talking about concepts or things in the real world that can be represented by a static class. As with System.Math, you may need only one way of taking the particular input and going away and getting the correct answer. There can be only one way of doing basic math - anything else is too specialised to be associated with the standard library. Another example might be a simple video game with only one room or one playing field.
  • hansvb
    hansvb over 6 years
  • Mohit Dharmadhikari
    Mohit Dharmadhikari almost 6 years
    The question is about when to use static class and not what you can do with static class.
  • Martin Schneider
    Martin Schneider about 3 years
    That answer sounds like using static classes and static members is a bad practice. But static is a language keyword and would not exist if it were bad practice to use it. I agree with @niico, the answer could focus more on the 'when to use' part.