Why after changing a static readonly field via reflection the output of that readonly field is old?

自闭症网瘾萝莉.ら 提交于 2020-01-13 05:06:28

问题


Why is the "someValue" variable which is readonly (but we still can change its value via reflection) output as "10", although it actually did change to 55?

static class Program
{
    static readonly int someValue = 10;

    static void Main(string[] args)
    {
        Console.WriteLine(someValue); // 10

        typeof(Program)
             .GetField("someValue", BindingFlags.Static | BindingFlags.NonPublic)
             .SetValue(null, 55); // change readonly field via reflection to 55

        Console.WriteLine(someValue); // output in console 10, 
                                      // but in visual studio debugger it shows 55

        Console.ReadKey();
    }
}

回答1:


Probably just a JIT optimization to prevent reading the variable multiple times.

You're changing a memory location you've declared as readonly, so shouldn't be surprised if readers cache the values.




回答2:


It is a JIT-compiler's optimization. JIT inlines static readonly fields.

Let me explain that.

Let's start with simple facts:

Static constructors are only called once in a process for each type.

So, static readonly field can only be initialized once, unlike instance readonly fields: instance constructor can be called multiple times (in order to create new instances of a class), so there can be multiple, different values when it comes to instance readonly fields. You can't inline some instance's readonly field in a method, because there might be other instances that method is working with.

When you access any type's or its instance's data or functions or whatever else, the static constructor of that type has already been called.

That means, static constructors are always called first when accessing a type. So, static readonly field must have already been initialized!

JIT-Compiler perfectly knows what i'm talking about above.

So, why not decide to inline that static readonly field in a method that's using it?

See, if a method is using that static readonly field, then it is accessing that type. If it is accessing that type, then static constructor of that type has already been called, and static readonly field has already been initialized. Static constructor will never be called again and static readonly field will have the same value until you don't restart the app! Why not inline it in a method if we know that field will always have the same value?



来源:https://stackoverflow.com/questions/54380905/why-after-changing-a-static-readonly-field-via-reflection-the-output-of-that-rea

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!