KregHEk
KregHEk

Reputation: 462

Why I can rewrite static readonly field after field initiaization by reflection?

As we know the static constructor is called the first time the class is called.

We now have a class:

static class Demo
{
    private readonly static int _intValue;

    static Demo ()
    {
        _intValue = 5;
    }
}

The constructor will be called when the Demo is accessed. The value 5 will be assigned to the _intValue readonly field. After that, we can once again set the value through reflection:

typeof (Demo)
  .GetField ("_ intValue", BindingFlags.Static | BindingFlags.NonPublic)
  .SetValue (null, 567);

Why value 5 can be overwritten? Isn't it already initialized in the constructor? Why isn't System.FieldAccessException thrown?

Tested in NET Core 3.1. Full example https://dotnetfiddle.net/4DsJ6H

UPDATED: I found a way to overwrite a read-only static field even after it was requested once. It is based on method generation via IL. Actually, in addition to the original question - how does this workaround work?

https://dotnetfiddle.net/oYaf5t

Upvotes: 0

Views: 643

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062600

Reflection is already breaking all the rules, including accessibility and mutability; it is effectively as powerful as unsafe: and just like unsafe: if something goes wrong, it is self inflicted and the runtime will laugh at you.

Note that in .NET Core, the runtime will sometimes stop you doing this, because of JIT optimisations that would become invalid if you did. But if it doesn't here: fine.

Note: you used to be able to change string.Empty via reflection. Imagine how well that ended :)

Upvotes: 1

Related Questions