Note that in this case IsLittleEndian
is actually a field and not a property. That has an effect on how the EE is able to process the value.
I tried this out locally and this is the behavior I saw
First i stepped until the cursor hit the var ticksBytes
line. At that point I observed that IsLittleEndian == false
. This is actually expected at this point. The EE does not always need to force a static constructor to run in order to read fields. Hence it is just reading the value as is and because no other code for BitConverter
has run the value is false
Immediately after stepping over that line I observe that IsLittleEndian == true
. The CLR ran the static constructor in order to execute the GetBytes
method and hence that set the field. The EE was then reading the set field.
Note that you can recreate this example with your own code. For example
static class Test {
static readonly bool example;
static Test() {
example = true;
}
internal static void Go() {
// example == true
}
}
class Program {
static void Main() {
// Test.example == false;
Test.Go();
}
}
Earlier I mentioned that the EE didn't always need to execute a static constructor in order to read fields. One case where it often needs to is when reading static fields off of a generic type. The storage for a static field of a generic type isn't created essentially until the CLR instantiates an instance of the type. Hence in order to read a field off of a generic type which hasn't yet been used the EE will create an instance under the cover in order to force the CLR to read it. For example
static class Test<T>
{
static readonly bool example = false;
static Test()
{
example = true;
}
}
If you add this to your program and then evaluate the following in the watch window
Test<int>.example
you will find that the value is true
clearly indicating the cctor
ran