C defines constants in two implementations

  • 2020-05-19 04:32:12
  • OfStack

There are two ways to define a constant in C#, one is called a static constant (Compile-time constant), and the other is called a dynamic constant (Runtime constant). The former is defined by "const" and the latter by "readonly". For static constants (Compile-time constant), it is written as follows:
public const int MAX_VALUE = 10;
Why is it called a static constant, because the above declaration can be understood as follows (note: the following is written incorrectly, resulting in a compilation error, just for illustration purposes).
public static const int MAX_VALUE = 10;
The constants defined by const are the same for all class objects, so you need to access the constants defined by const as if they were static members, and it would be a mutating error to access them as if they were members of an object. In addition, the access to static constants at compile time is to replace the constant with the value of the constant, such as:
int nValue = MAX_VALUE;
After compiling, this sentence is identical to the intermediate language code generated by the following sentence.
int nValue = 10;
However, when defining constants using const, there are a number of restrictions on the type. First, this type must be a value type, and the initialization of this type cannot be done by new, so some value type constants defined by struct cannot be defined by const.
Using readonly to define constants is much more flexible than using const. It is written as follows:
public readonly int MAX_VALUE = 10;
Why dynamic variables? Because the system allocates space for constants defined by readonly, that is, it has a separate space from other members of the class. In addition, the constants defined by readonly can be set in the constructor of the class, in addition to the constant values that can be set at the time of definition. Since the constants defined by readonly are equivalent to the members of the class, the type restrictions imposed by using const to define constants completely disappear when using readonly to define, that is, readonly can be used to define constants of any type. In summary, the differences between the two are as follows.

Static constant (Compile-time constant) dynamic constant (Runtime constant)
Define the declaration while setting the constant value. You don't need to set the constant value when you declare it, you can set it in the constructor of the class.
Type restriction first of all, a type must be in the range of value types, and its value cannot be set by new. There is no limit to using it to define any type of constant.
For class objects for all class objects, the value of the constant is one. The value of a constant can be different for different objects in a class.
No memory consumption. To allocate memory, save the constant entity.
Summary performance is slightly higher, with no memory overhead, but it is limited and inflexible. Flexible and convenient, but with slightly lower performance and memory overhead.

As for whether to use const or readonly when defining constants, I tried to use const for performance. However, in this book, there is a reference to the potential bug generated by the use of const. When the static constant of a class of DLL class library is used in the program, if the value of the static constant is modified in the class library, other interfaces do not change. Generally speaking, the calling side of the program does not need to be recompiled, but can be directly executed to call the new class library. But that's where the potential bug comes in. This is because static constants are replaced with their values at compile time, and thus are replaced by programs on the calling side. For example, a static constant is defined in the class library, as follows:
public const int MAX_VALUE = 10;
So the code that calls this static constant in the program, in the intermediate language code that's generated after compilation, is replaced by 10, even where static constants are used, by 10. Then when the static variable of the class library changes, for example:
public const int MAX_VALUE = 15;
Then the calling side program can be run without recompiling, but the program's intermediate language code corresponds to a static variable value of 10, not 15 in the new class library. So if this does not produce a 1, the program will trigger a potential bug. The solution to this problem is for the calling side program to recompile 1 after updating the class library, which generates the new intermediate language code.

For the potential bug that existed when const defined constants as above, it does not occur when readonly defined constants. Because the constants defined by readonly are similar to the members of a class, they need to be accessed at a specific constant address to avoid bug.
For this reason, the book suggests readonly instead of const to define constants.

Related articles: