const
is used to represent values that will never change throughout the lifetime of the program. Its value is constant from compile-time, as opposed to the readonly
keyword, whose value is constant from run-time.
For example, since the speed of light will never change, we can store it in a constant.
const double c = 299792458; // Speed of light
double CalculateEnergy(double mass)
{
return mass * c * c;
}
This is essentially the same as having return mass * 299792458 * 299792458
, as the compiler will directly substitute c
with its constant value.
As a result, c
cannot be changed once declared. The following will produce a compile-time error:
const double c = 299792458; // Speed of light
c = 500; //compile-time error
A constant can be prefixed with the same access modifiers as methods:
private const double c = 299792458;
public const double c = 299792458;
internal const double c = 299792458;
const
members are static
by nature. However using static
explicitly is not permitted.
You can also define method-local constants:
double CalculateEnergy(double mass)
{
const c = 299792458;
return mass * c * c;
}
These can not be prefixed with a private
or public
keyword, since they are implicitly local to the method they are defined in.
Not all types can be used in a const
declaration. The value types that are allowed, are the pre-defined types sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, char
, float
, double
, decimal
, bool
, and all enum
types. Trying to declare const
members with other value types (such as TimeSpan
or Guid
) will fail at compile-time.
For the special pre-defined reference type string
, constants can be declared with any value. For all other reference types, constants can be declared but must always have the value null
.
Because const
values are known at compile-time, they are allowed as case
labels in a switch
statement, as standard arguments for optional parameters, as arguments to attribute specifications, and so on.
If const
values are used across different assemblies, care must be taken with versioning. For example, if assembly A defines a public const int MaxRetries = 3;
, and assembly B uses that constant, then if the value of MaxRetries
is later changed to 5
in assembly A (which is then re-compiled), that change will not be effective in assembly B unless assembly B is also re-compiled (with a reference to the new version of A).
For that reason, if a value might change in future revisions of the program, and if the value needs to be publicly visible, do not declare that value const
unless you know that all dependent assemblies will be re-compiled whenever something is changed. The alternative is using static readonly
instead of const
, which is resolved at runtime.