📜 ⬆️ ⬇️

Constants do not change: a small excursion into the depths of dotNet

image Greetings. I recently stumbled upon Comrade Dywar 's article “Interesting Notes on C # and CLR” and became interested in paragraph 13:

“The constants are placed in the assembly metadata, so if there were changes, you need to recompile all the assemblies that use it. Since DLL with a constant may not even load. "

Come on, I thought, and it was useful to set up experiments. Created a TestConstants project, in it a class,
')
public class Master { public const string Const = "Hello world"; } 

then the TestConstantsSlave project,

 static void Main() { Console.WriteLine(Master.Const); Console.ReadKey(); } 

Replaced the constant with “Hello habr”, rebuilt the main project, launched F5 ...

“Hello habr” flashed on the console. Apparently, the studio also rebuilt the Slave project. In principle, it was possible to calm down on this, but I wanted to experiment a little.

First of all, I replaced the constant with “Greetings, sir von Neumann”, rebooted the main project, and launched Slave through the conductor → TestConstantsSlave.exe. “Hello habr” shone on the console, forgive me the great Neumann. I copied a fresh library to Slave - still “Hello habr”. Removed the TestConstants library - again “Hello habr”. Habr was silent.

Is it really a constant copied to metadata? Open ildasm. In the Slave manifest, everything is standard: version, headers, tokens. There is no constant (which is reasonable). Ran through classes - no metadata was explicitly detected.

But in the Slave code there is “Hello habr” explicitly.

ildasm

See the description of the ldstr instruction on msdn . “Pushes a string reference for a metadata”. Apparently, the metadata is hidden for ildasm. Just in case, I checked dotPeek - the result is similar (but it is clear that the Slave project does not refer to TestConstants).

Checking a constant of another type: using an Int32 constant gives another il code: ldc.i4.5. Here we have a simple push into the stack (which is again reasonable - the lines are long, it makes sense to cache them, but the overhead of pulling the inta out of the cache outweighs the exhaust). Apparently, in the original article and msdn, metadata means part of the string interning mechanism ( tuna , tynz ), which, by the way, explains the lack of metadata in ildasm - a pool of lines is generated for the process.

So, what is next?


Nothing wrong. The studio is a correct build, and the constants do not change every day. On the other hand, I have already worked with the project, where the SDK and the utilities using it were in different solutions, and updating the SDK could generate a “constant bug”.

Source: https://habr.com/ru/post/309150/


All Articles