Suppose there is a class in a DLL:
1 //Lib.dll2 Public classLib3 {4 Public Const stringVERSION ="1.0";5 Public Static voidPrintVersion (stringVersion ="1.0")6 {7 Console.WriteLine (version);8 }9}
Then there is this caller:
// Program.exe class program{ staticvoid Main () { Console.WriteLine (lib.version); Lib.printversion (); Console.read (); }}
The results of Program.exe's operation are obvious:
1.0 1.0
After a while, Lib updated the version:
// Lib.dll Public class lib{ publicconststring"2.0"; Public Static void PrintVersion (string"2.0") { Console.WriteLine ( version);} }
Recompile the Lib.dll to make sure that Program.exe references the latest DLL before running Program.exe, the result:
1.0 1.0
Recompile Program.exe to run again after:
2.0 2.0
Discover the problem, the caller must recompile to ensure that the values of the optional parameters and constants are up to date.
The reason is this:
1. methodPrivateHidebysigStatic 2 voidMain () cil managed3 {4 //Method begins at RVA 0x20505 //Code Size (0x1e)6. maxstack87 . EntryPoint8 9Il_0000:ldstr"1.0"TenIl_0005:callvoid[mscorlib] System.console::writeline (string) OneIl_000a:ldstr"1.0" AIl_000f:callvoidCsconsole.program/lib::P rintversion (string) - il_0014:call Int32 [Mscorlib]system.console::read () - Il_0019:pop the Il_001a:ret -}
This is the first compilation of the Program.main method after the il,lib.version is completely compiled into the literal "1.0" (line 10th), and the 11th line of "1.0" is derived from (at the time of the first compile) Lib.dll metadata.
Obviously, no matter how to update the LIB code, as long as the program is not recompiled, there is no way to update the two values, and the actual production environment is often not guaranteed that the caller will be recompiled.
As for why this is compiled, I understand that.
The value of a constant is in a constant pool, and it is obviously better to take it from a constant pool than to take it directly from the member of the class.
The implementation of the optional parameters is to make a judgment and assignment at compile time, which saves the runtime time.
Workaround:
For optional parameters, the method recommended by CLR via C # is this:
1 Public Static voidPrintVersion (stringVersion =NULL)2 {3 if(Version = =NULL)4 {5Version ="1.0";6 }7 Console.WriteLine (version);8}
It is clear that this code behaves as it did before, but most of the time it does solve the problem of updating the value, but it also brings up the problem of runtime efficiency.
For constants, as can be seen from the example I use, the value of the version number should not be defined as a constant, and the readonly can be used to achieve the purpose.
For true constants, it is not easy to change its value.
Finally, Java does not have a const, but static final also has the same performance, also need to pay attention to this point.
[C #] Optional parameters and constant considerations for cross-module