Constants are members that represent constant values. A constant-declaration introduces one or more constants of a given type.
A constant-declaration may include set of attributes (§17), a new
modifier (§10.2.2), and a valid combination of the four access modifiers (§10.2.3). The attributes and modifiers apply to all of the members declared by the constant-declaration. Even though constants are considered static members, a constant-declaration neither requires nor allows a static
modifier.
The type of a constant-declaration specifies the type of the members introduced by the declaration. The type is followed by a list of constant-declarators, each of which introduces a new member. A constant-declarator consists of an identifier that names the member, followed by an "=
" token, followed by a constant-expression (§7.15) that gives the value of the member.
The type specified in a constant declaration must be sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, char
, float
, double
, decimal
, bool
, string
, an enum-type, or a reference-type. Each constant-expression must yield a value of the target type or of a type that can be converted to the target type by an implicit conversion (§6.1).
The type of a constant must be at least as accessible as the constant itself (§3.3.4).
A constant can itself participate in a constant-expression. Thus, a constant may be used in any construct that requires a constant-expression. Examples of such constructs include case
labels, goto
case
statements, enum
member declarations, attributes, and other constant declarations.
As described in §7.15, a constant-expression is an expression that can be fully evaluated at compile-time. Since the only way to create a non-null value of a reference-type other than string
is to apply the new
operator, and since the new
operator is not permitted in a constant-expression, the only possible value for constants of reference-types other than string
is null
.
When a symbolic name for a constant value is desired, but when type of the value is not permitted in a constant declaration or when the value cannot be computed at compile-time by a constant-expression, a readonly
field (§10.4) may be used instead.
A constant declaration that declares multiple constants is equivalent to multiple declarations of single constants with the same attributes, modifiers, and type. For example
class A { public const double X = 1.0, Y = 2.0, Z = 3.0; }
is equivalent to
class A { public const double X = 1.0; public const double Y = 2.0; public const double Z = 3.0; }
Constants are permitted to depend on other constants within the same project as long as the dependencies are not of a circular nature. The compiler automatically arranges to evaluate the constant declarations in the appropriate order. In the example
class A { public const int X = B.Z + 1; public const int Y = 10; } class B { public const int Z = A.Y + 1; }
the compiler first evaluates Y
, then evaluates Z
, and finally evaluates X
, producing the values 10
, 11
, and 12
. Constant declarations may depend on constants from other projects, but such dependencies are only possible in one direction. Referring to the example above, if A
and B
were declared in separate projects, it would be possible for A.X
to depend on B.Z
, but B.Z
could then not simultaneously depend on A.Y
.