Preface: Starting from last week, I saw <CLR via C #> the third edition. I have just finished reading chapter 4 and Chapter 7. Both sections are common sense, however, there are a lot of basic knowledge and terminology that are not very in-depth, so it looks a little slow. I plan to write snacks every two weeks.
1. Application Scenario Reproduction
A simple applicationProgramThe solution is as follows:
The csharplib class library defines a simple sometype class as follows:
Namespace csharplib {public class sometype {public const int constfield = 50; public static readonly int readonlyfield = 50 ;}}
Reference the class library csharplib in the consoleapp of the console application, and write down the followingCode:
Using system; namespace consoleapp {using csharplib; Class program {static void main (string [] ARGs) {console. writeline ("const field is {0 }. ", sometype. constfield); console. writeline ("readonly field is {0 }. ", sometype. readonlyfield); console. readkey ();}}}
In this way, the output of this console application is 50, and the result should be expected by every developer, without any suspicious points.
When we change the constants in the class library csharplib:
Namespace csharplib {public class sometype {public const int constfield = 55; public static readonly int readonlyfield = 5555 ;}}
That is to say, our expected target output is 55 and 5555. The limit file, we are surprised to find that the current output is not 55 and 5555, but 50 and 5555, that is, the const field is not modified to achieve the expected purpose.
2. Notes
Why is the above phenomenon? Start with the essence of constants in C.
(1) What is a constant (Extract from the original Chinese)
A constant is a special symbol that never changes. When defining a constant symbol, its value must be determined during compilation. After confirmation, the compiler saves the constant value to the metadata of the Assembly. Constants are always regarded as static members rather than instance members.When the code references a constant symbol, the compiler searches for the symbol in the metadata of the Assembly that defines the constant, extracts the value of the constant, and embeds the value in the generated il code. Since the constant value is directly embedded into the code, you do not need to allocate memory for the constant during runtime.In addition, the constant address cannot be obtained, or the constant cannot be transferred as a reference. These restrictions also mean that constants do not have a good cross-assembly version control feature. "
(2) Static constants and Dynamic Constants
To put it simply, const is a static constant (compile-time constants), and it is implicitly static. The value of a dynamic constant (runtime constants) is obtained at runtime. Il marks it as a read-only constant rather than a constant value.
The following is a simple comparison of the two features:
& Lt; TD width = "188" valign = "TOP" & gt; & lt;/TD & gt;
static constant |
dynamic constant |
memory allocation |
none |
Yes |
available types |
less C # primitive types, such as string and int32 |
Any type |
initialization value assignment |
assign values when declaring variables |
values can be assigned to constructors |
when to take effect |
Replace the data during compilation to generate metadata |
equivalent to a data member in the class |
Through the above analysis, we can understand the Output Inconsistency in 1, because the const field constfield has been embedded in the Il code of the console application (obtaining the constfield field is not loaded from the DLL file of the Class Library), we can see clearly from the Il:
. Method private hidebysig static void main (string [] ARGs) cel managed {. entrypoint // code size 47 (0x2f ). maxstack 8 il_0000: NOP il_0001: ldstr "const field is {0 }. "il_0006: LDC. i4.s 50 // The const field has not changed. Il_0008: Box [mscorlib] system. int32 il_000d: Call void [mscorlib] system. console: writeline (string, object) il_0012: NOP il_0013: ldstr "readonly field is {0 }. "il_0018: lds1_int32 [csharplib] csharplib. sometype: readonlyfield il_001d: Box [mscorlib] system. int32 il_0022: Call void [mscorlib] system. console: writeline (string, object) il_0027: NOP il_0028: Call valuetype [mscorlib] system. consolekeyinfo [mscorlib] system. console: readkey () il_002d: Pop il_002e: Ret} // end of method program: Main
Instead of loading the class library assembly from memory like the static readonly field. If the application needs to obtain a new value, it must also be re-compiled or use the readonly field.
3. analogy
I remember a previous blog post discussing output inconsistencies in enumeration usage. I Googled it. You can refer to this article to carefully compare enumeration traps. If you have an understanding of Il, you can analyze and compare it from Il to better understand it.
conclusion : const and readonly are often used in programming practices. Understanding their basic principles is necessary for development and maintenance. When developing and defining constants in a class library, I prefer to use static readonly combination keywords.