The declaration of a const data member must include an initial value. Moreover, that initial value must be a constant expression—that is, an expression that can be fully evaluated at compile time. For example, the code fragment
class Matrix { private const int ms_default_row_size = 4, ms_default_col_size = 4;
declares two const int members initialized with a value of 4. An attempt to modify a const member generates a compile-time error.
A const member can always be initialized with another const member, provided there is no circular dependency. For example, the three const declarations below compile without error, setting x to 10, y to 8, and z to 4:
class Illustrate { // OK: no circular dependency private const int x = y + z/2; private const int y = z * 2; private const int z = 4; }
The next example, however, results in a compile-time error because of the circular dependency between the definitions of x and z:
class Illustrate { // error: circular dependency private const int x = y + z/2; private const int y = z * 2; private const int z = x; }
A const data member is not an instance member. Only a single instance of the const member exists. A const member is essentially a read-only static member: Qualified access must be through the class name and not through an object of the class.
A const member cannot be a reference type. Take a moment to think why. A reference type requires an invocation of operator new. Operator new cannot be evaluated until runtime. We must initialize a const member with an expression that can be evaluated at compile time. For example, the following declaration is illegal and generates a compile-time error:
// illegal: cannot be evaluated at compile time public const Matrix identity = new Matrix( 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1 );
readonly allows us to initialize an object at runtime but enforce read-only access. An attempt to modify a readonly member generates a compile-time error. To simulate a const member, we can declare the readonly member as static-for example,
public static readonly Matrix identity = new Matrix( 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1 );
The only reference type that can be declared const is the string type, which, if you recall, is initialized without use of the new expression—for example,
class Illustrate { // OK: string reference type is an exception private const string default_login = "Guest"; private const string default_pswrd = "ChangeMe"; }
The primary difference between a const and a readonly member is the different initialization time (compile time versus runtime). Because the value of a const is available at compile time, it can be constant-folded (i.e., substituted) at each occurrence of its name. This is not possible for a readonly member.
3.135.216.75