private class TestReadOnly
{
public static readonly int Field;
}
[TestMethod]
public void TestReadOnlyField()
{
FieldInfo field = typeof(TestReadOnly).GetField(nameof(TestReadOnly.Field));
Console.WriteLine(field.GetValue(null));
field.SetValue(null, 0xFF);
Console.WriteLine(field.GetValue(null));
Console.WriteLine(TestReadOnly.Field);
}
Output:
0
255
255
0
The environment is .Net Standard 2.0
core dll:
Microsoft.NETCore.App 2.1
Static readonly fields get baked into the generated asm where they are used when Jitted; this also means that asm has branch elimination and devirtualisation happen on it due to the value of the field so its not possible to undo that by changing its value.
In .NET Core 3.0 it now throws this exception if you try to change the static readonly:
System.FieldAccessException: Cannot set initonly static field 'Field' after type 'TestReadOnly' is initialized.
Related issue which discusses it more: https://github.com/dotnet/coreclr/issues/21268
Most helpful comment
Static readonly fields get baked into the generated asm where they are used when Jitted; this also means that asm has branch elimination and devirtualisation happen on it due to the value of the field so its not possible to undo that by changing its value.
In .NET Core 3.0 it now throws this exception if you try to change the static readonly:
Related issue which discusses it more: https://github.com/dotnet/coreclr/issues/21268