Static qualifier at a class level versus member level (in C#)
The static qualifier is available at both the class level as well as the individual member level (both fields and methods) in C#. This article discusses when to use it a the class level versus when it makes sense to use it at the member level.
‘Static’ qualifier at a class level
When you want to ensure that your class only contains static members – and no accidental instance fields/members. The compiler will help ensure this if the class is marked as static. An example would be a Utility classs where every user of the class will need to use exactly the same ‘instance’ and the same methods in the instance (note that a static class is never strictly ‘instantiated’ – it doesn’t live on the normal heap but rather in a special heap called the Loader Heap. This makes sense because anything on the heap is going to get garbage collected – and you would not want your static class to be garbage collected.). Static classes are less common than instance classes with a few static members (described below). Before we get to those, here are some examples of when you would need to use ‘static’ at a class level:
A utility class – Typically – you will not need any instance methods inside your utility class. That would defeat the purpose of providing the same utility methods to all consumers of the utility methods in the class.
A struct converter class (or any converter in general) – Suppose your application has a variety of data structs – your own defined user-types which are used throughout your application. You may need to convert back and forth between different data types. A simple example would be if you had a Dollar class and a Euro class and needed to go back and forth between these. You could define a static CurrencyConverter class as shown below:
So – at the class level, Utility classes, Conversion classes etc. are ideally suited for the static qualifier.
Code Snippet
- /// <summary>
- /// Utility class used for doing conversions – ideal candidate for 'static' (one instance only) class
- /// </summary>
- static class CurrencyConverter
- {
- static Euro ConvertToEuro(Dollar inDollar)
- {
- // do conversion…
- return euro;
- }
- static Dollar ConvertToDollar(Euro inEuro)
- {
- // do conversion…
- return dollar;
- }
- }
Static Members (Instance classes with static members)
This is the more commonly used form of the ‘static’ qualifier. Members of instance classes often need to marked ‘static’. The basic criteria is: is there any member variable that is common across all instances of this class? For e.g. – in an Employee class – even though each employee instance is unique – they all belong to the same ‘Employer’ – hence a field called EmployerName (or EmployerID) inside an Employee class would be a good candidate for being marked ‘static’.
Code Snippet
- class Employee
- {
- // common across all instances
- static string _employerName = "Microsoft";
- // unique to each instance
- int _employeeId;
- string _employeeName;
- }
Another example may be if you are trying to model cars. The number of ‘wheels’ on each of your car instances would always be 4.
Code Snippet
- class Car
- {
- // 'static' makes this common across all instances
- static string _numWheels = 4;
- // unique to each instance
- int _milesPerGallon;
- string _make;
- }
In summary, while C# offers the ‘static’ qualifier at both the class level as well as individual member level, it is rare to use it at the class level – except for utility classes. The real advantage of static at the class level is having the compiler ensure for you that there are no instance level members in your class. In practice, one finds a lot more use of regular, non-static classes – which have the occasional static members to deal with commonality across all instances.
Leave a Reply