Catalogue
- What are static constants (const) and dynamic constants (Readonly)
- The difference between a static constant (CONST) and a dynamic constant (Readonly)
- Dynamic Constants (Readonly) cannot be changed after being assigned
- Summarize
what are static constants (const) and dynamic constants (Readonly)
First explain what the static constant (const) is and what the dynamic constant (Readonly) is.
A static constant (Const) is a compiler that parses a constant at compile time and replaces the value of the constant with the initialized value.
The value of the dynamic constant (Readonly) is obtained at the moment of execution, and is marked as a read-only constant during compiler compilation, instead of the constant value, so that the dynamic constant does not have to be initialized at the time of declaration, but can be deferred to the constructor initialization.
the difference between a static constant (CONST) and a dynamic constant (Readonly)
|
Static Constants (Compile-time Constant) |
Dynamic Constants (Runtime Constant) |
Defined |
A constant value is set at the same time as the declaration. |
When declaring a constant value, you can set it in the constructor of the class. |
Type restrictions |
Only primitive types, enumeration types, or string types can be decorated. |
There is no limit, and you can use it to define constants of any type. |
For class objects |
For all classes of objects, the value of the constant is the same. |
For different objects of a class, the value of the constant can be not the same. |
Memory consumption |
No. |
To allocate memory, save the constant entity. |
Review |
High performance, no memory overhead, but a lot of restrictions, inflexible. |
Flexible and convenient, but with slightly lower performance and memory overhead. |
- Const-Modified constants must be initialized at the time of Declaration; ReadOnly-Modified constants can be deferred to constructor initialization.
- Const constants can be declared either in a class or in a function body, but static readonly constants are declared only in a class. Const is a static constant, so it is inherently static, so you cannot manually add a static modifier to the Const.
- Const-Modified constants are parsed during compilation, that is: when compiled by the compiler, we all refer to the const variable in code where the actual value corresponding to the const variable is substituted; ReadOnly-Modified constants are deferred until run time.
Give an example to illustrate:
Public Static ReadOnly intNumbera = Numberb *Ten; Public Static ReadOnly intNumberb =Ten; Public Const intNUMBERC = numberd*Ten; Public Const intNumberd =Ten; Static voidMain (string[] args) {Console.WriteLine ("Numbera is {0} and Numberb is {1}.", Numbera, Numberb);//Numbera is 0, Numberb is ten.Console.WriteLine ("Numberc is {0} and Numberd is {1}.", Numberc, Numberd);//Numberc is, Numberd is ten.Console.readkey (); }
View Code
The above is the grammatical application, that in the actual usage, still some subtle changes, usually not easy to find.
Give an example to illustrate:
There is a class MyClass in assembly DoTestConst.dll that defines a public static variable count
Public Static class MyClass { publicconstintten; }
Then another application references DoTestConst.dll and makes the following call in the code:
Public Static void Main (string[] args) { Console.WriteLine (DoTestConst.MyClass.Count); // Output Ten Console.readkey (); }
Without a doubt, very simple code, direct output 10.
Next update the count value of MyClass to 20, then recompile DoTestConst.dll and update to the directory where the application is located, and be careful not to compile the application . Then the output is expected to be 20, but actually 10, why?
This is the special point of the const, how special it is to look directly at the generated IL, and look at the IL code (assuming that this time the value of Count is 10)
Il_0000:nop
IL_0001:LDC.I4.S 10
Il_0003:call void [Mscorlib]system.console::writeline (Int32)
The red code clearly shows that the direct load of 10, not by any type of loading and then get the corresponding variable, that is, when the runtime does not load DoTestConst.dll, then does it mean that no DoTestConst.dll can be run? The answer is yes, delete DoTestConst.dll can also run, whether it is very strange? It also explains the previous experiment, why the new value is not called after updating the value of the const variable, because the program does not load DoTestConst.dll at all when it is running. So where does the 10 value come from? In fact, the CLR has a special handling of const variables, which is to embed the const value directly in the generated IL code and will not be loaded from the DLL at execution time. This also brings a bug that is not easy to detect, so when referencing the const variables of other assemblies, you need to consider the issue of version updates, to solve this problem is to compile the calling application once again OK. However, the actual program deployment update may only update individual files, this time you must use the ReadOnly keyword to solve this problem.
Next look at the version of ReadOnly:
Public Static class MyClass { publicstaticreadonlyint; }
The caller code is the same, followed by the generated IL code:
Il_0000:nop
IL_0001:LDSFLD Int32 [Dotestconst]dotestconst.myclass::count
Il_0006:call void [Mscorlib]system.console::writeline (Int32)
Obviously the loading code has changed, a very common ldsfld action that requests the Dotestconst.myclass count variable is implemented by forcing the loading of the dotestconst. Therefore, after the value of the update count is recompiled, the calling program is not compiled, and then execution sees the new value. At this point, if you delete DoTestConst.dll, you will see an exception such as a DLL. This also fully illustrates that variables defined for ReadOnly are loaded at run time.
Dynamic Constants (Readonly) cannot be changed after being assigned
The ReadOnly variable is a run-time variable that cannot be changed after the first assignment at run time. Where "can not be changed" is divided into two meanings:
- For value type variables, the value itself cannot be changed (Readonly, read-only)
- For reference type variables, the reference itself (equivalent to a pointer) cannot be changed.
A value type variable, for example:
Public class Student { publicreadonlyint age ; Public Student (int. ) { this. Age = Age ; } }
An instance of student cannot be changed after it has been assigned in the constructor, and the following code is not compiled by:
New Student// error message: Cannot assign a value to a read-only field (except in constructors or variable initializers)
A reference type variable, for example:
Public classStudent { Public intAge;//Notice here that age is not readonly modifier. PublicStudent (intAge ) { This. Age =Age ; } } Public classSchool { Public ReadOnlyStudent Student; PublicSchool (Student Student) { This. Student =student; } }
The student of a school instance is a variable of a reference type, and after the assignment, the variable cannot point to any other student instance, so the following code will not compile through:
New School (new Student (new Student); Error Message: Cannot assign value to a read-only field (except in constructors or variable initializers)
The reference itself cannot be changed, but the value of the reference point to the instance can be changed. So the following code can be compiled by:
New School (new Student (ten;
public class Student { public readonly
int age =
20 ;
//
Note: The initializer is actually part of the construction method, which is actually a syntactic sugar
public Student (
int
age) {
this . Age =
this . Age = 25 ; this . Age = 30 ; } }
Summary
The biggest difference between const and readonly (except syntax)
The const variable is embedded in the IL code and is loaded at compile time, independent of the external DLL (which is why it is not possible to assign a value in the constructor method). Const is prone to version inconsistencies when an assembly is updated.
The readonly variable is loaded at run time and requires a request to load the DLL, each time getting the most recent value. ReadOnly an assignment reference type, the reference itself cannot be changed, but the value of the instance to which the reference is directed can be changed. In the construction method, we can assign a value to the ReadOnly multiple times.
The difference between-readonly and const in C # basic knowledge points