In C#.Net we have two ways to establish a value that is constant (which means that its value will not be modifiable). The first way is the old one, making a const variable (maybe you know it as #define), the second one is to make a readonly variable.
The most important difference between them is that a const will be evaluated at compile time while a readonly variable will be evaluated at run time. This limits the possibilities with consts since you cannot, for example, declare const structures, as they will need to call a constructor and that has to be made in run time, but you still can attach some expressions to it as soon as it can be resolved in compilation time.
public const int NUM_MONTHS = 12; public static readonly int daysInWeek = 7; // This is also valid since it will be resolved in compilation time: public const int SECONDS_PER_DAY = 60*60*24;
Main differences:
Const
- Value is evaluated at compile time.
- Can be declared as class member or inside a method.
- Is always static.
- Can only be initialized at declaration.
- Non-standard convention establish to name them with uppercase letters separated by underscores.
Readonly
- Value is evaluated at run time.
- Is not allowed inside a method.
- Can be static or instanceable.
- Can be initialized at declaration or in the constructor
- Are named as a normal variable.
Since readonly can be instanceable it could be used for having a constant which value could be defined in run time and which value could vary from object to object like this:
public readonly DateTime dateInitialized = DateTime.Now;
Warnings
Take into account that when you access a static readonly value you will force the constructor of that class to run whereas this is not the case with const values.
If you make a const in A.DLL and reference it from B.DLL, the value of that const will be compiled in B.DLL. If you then modify the value of that const in A.DLL, B.DLL will still be using the old value since it has not been compiled again. This could end in a dramatic error and is why it is not recommended to use consts unless you are totally sure that that value is not going to be changed and, for more safety, its not going to be called from another class.
Remember that readonly applies to the field itself and not the value. This means that readonly value types can’t be changed at all. But with references, the only thing that is readonly is the reference itself!
When should we use each one?
Since read only variables will be made at run time it will be less efficient than const in time consuming, but since we are talking about small data this will not be noticeable. Instead, as we have seen, read only can be more safe, so it is a better idea to use read only normally and be sure that nothing will crash in the future.
Also, you will need to use readonly when making something that cannot be determined in compile time like an instanceable constant (non static) or an struct or a non-null non-string class since you cannot use const on these cases.
You can, though, use a const if you are sure its value will never ever change (like daysPerWeek) and, for most safety, that const its not going to be used out of that class. Then you would have something safe and more efficient.
Source: I have read many sources and, when I had nearly finished this post, found a Black Rabbit Coder who made an amazing post about this issue.