10

While just playing with c#, realized a strange thing.

Here is the code:

class Program
{
    static void Main(string[] args)
    {
        System.Diagnostics.Debug.Write(string.Empty);

        typeof(string)
            .GetField("Empty", BindingFlags.Static | BindingFlags.Public)
            .SetValue(null, "Tolgahan");


        Console.WriteLine(string.Empty);

        // output : Tolgahan
    }
}

Why reflection let us to change readonly fields?


The question is "why the setting via reflection is allowed", not "how to do it", so it is not a duplicate of Can I change a private readonly field in C# using reflection?.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Tolgahan Albayrak
  • 3,118
  • 1
  • 25
  • 28
  • 5
    You can do all sorts of things with reflection that you can't do normally. You can get/set private fields from other classes, for example. I'm almost certain this isn't a bug; as to whether or not it's desirable is another story. – Servy Aug 30 '12 at 16:07
  • 4
    To steal a quote, readonly is to protect against "Murphy, not Machiavelli" – Damien_The_Unbeliever Aug 30 '12 at 16:09
  • @Dennis: The other question just asks whether it's possible, this one states that it is possible, but asks why (and is therefore IMO much more valuable than the other one). – O. R. Mapper Aug 30 '12 at 16:11
  • @O.R.Mapper: look at Eric Lippert's comment more attentively. There's an explanation. – Dennis Aug 30 '12 at 16:15
  • If all thats left is "why is this possible" I don't expect a definitive answer unless the chief designers of .Net have a meeting and compose a unified response. – Jodrell Aug 30 '12 at 16:18
  • @Dennis: I have seen that someone says it, but that wasn't in the question. Therefore, this is evidently a different question. I'm sure many answers to other questions happen to contain additional information, but that doesn't make questions that explicitly ask for that information exact duplicates of other questions. There's a distinction between comments and answers for a reason. (That doesn't mean the OP couldn't have found that explanation on his own, of course.) – O. R. Mapper Aug 30 '12 at 16:21
  • Not to be a nitpicker, but.. you're asking about readonly fields, but your example is about a static field. The question is still valid though. – Arjen de Mooij Jul 25 '16 at 09:27

3 Answers3

19

In the same way the laws of chemistry say that no reaction can cause an atom of one element to change into an atom of another element, but the laws of physics say it happens all the time. Chemistry is a restricted subset of physics in order to simplify problems into a more solvable manner.

Reflection is the physics in this case, where normal programming is the chemistry. It operates in a simpler mindset. Reflection allows you to circumvent that simpler set of rules, exposing you to new processes, but also new dangers.

corsiKa
  • 81,495
  • 25
  • 153
  • 204
5

Because readonly, like private, guards against Murphy, not Machiavelli*.

We use readonly and private and anything else that restricts what we can do, primarily because we have hopefully restricted more incorrect, inconsistent, or just plain stupid things, than we have useful and fruitful things.

But it's still just ones and zeros. If some memory is set to the number "42" and we access it through a readonly field, it wasn't readonly when the object was being created. There's nothing stopping it from being changed except the compiler spotting "hey, first you said you didn't want to change it, now you're trying to change it, what gives? One of those two decisions must be wrong".

Now, there's no promise that reflection will be able to change it, but there's no promise that it won't. Right now, the way reflection works and the way readonly works means that you can change it. At the very least, it would take a lot of work (perhaps with costs affecting us users as well as the team who needs to implement that work) to stop someone who'd presumably gone to the bother of doing this because they thought they had a good reason.

Note that the permissions relating to reflection do stop Machiavelli,

*Strictly, Murphy was talking about precisely how we should design things to stop people accidentally doing something disasterous - readonly is a good example, plugs that can't physically be plugged in the wrong way around a better - and Machiavelli was teaching rather than practising the techniques. It makes for nowhere near as concise a saying though.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • @p.s.w.g that of Murphy and Machiavelli? I can't claim the credit. The earliest comparable use (about `private` in C++) I know of was by Bjarne Stroustrup, though I don't know if he was the first. – Jon Hanna Jun 12 '14 at 11:53
0

Its possible because Reflection in .Net was implemented this way. I can only guess at the motivation for this but, it is a powerful (but slow) tool that offers great flexibility and potential for misuse.

It's not the only way such an alteration could be achieved but such discussions are off topic and out of place like any further subjective speculation.

Jodrell
  • 34,946
  • 5
  • 87
  • 124