Your question is what is going on in .NET at a really low level. What really happens when running JIT and optimized code may be different than expected.
However, the way to answer your question is to look at the generated IL:
string hi = "HelloWorld"; int length = hi.Length; Console.WriteLine(length); Console.WriteLine(length);
compiles to
ldstr "HelloWorld" callvirt System.String.get_Length dup call System.Console.WriteLine call System.Console.WriteLine
and
string hi = "HelloWorld"; Console.WriteLine(hi.Length); Console.WriteLine(hi.Length);
(where I removed the length assignment because it is not used) compiles to
ldstr "HelloWorld" dup callvirt System.String.get_Length call System.Console.WriteLine callvirt System.String.get_Length call System.Console.WriteLine
The first version looks a bit more efficient than the second, because there is only one call to System.String.get_Length , and both use an extra stack location ( dup ). However, JIT'er could possibly have built in this call, which would then use indirection to read the value from the memory location, and then there is hardly any difference.
Note that the .NET string type stores the length of the string in the string object, so there is no need to count the characters in the string. The length is known when creating a string.
source share