4

Given the code below, I'm very surprised that an exception is not thrown and would like to know why not. I have a class that has a readonly field that is initialized in the constructor. I then use reflection to get the FieldInfo and call the SetValue method. This results in the otherwise read-only field being writable. My question is why is this allowed to happen?

If this is allowed to happen, that means the readonly keyword is purely for compile-time checking and has very little bearing on the actual instruction generation, I would assume. Thanks in advance for your insights.

public class SomeType
{
    public readonly int RONumber;

    public int LocalMember;

    public SomeType()
    {
        RONumber = 32;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var st = new SomeType
        {
            LocalMember = 8
        };

        var ron1 = st.RONumber;

        var type = typeof(SomeType);

        var ronField = type.GetField("RONumber");

        ronField.SetValue(st, 405);

        var ron2 = st.RONumber; // ron2 is 405!
    }
}
Will Custode
  • 4,576
  • 3
  • 26
  • 51
  • 1
    `readonly` fields are a C# language feature, not a CLR feature. The Reflection API is not bound by the rules of the C# language. – Mike Zboray Aug 11 '15 at 17:24
  • 2
    If your question is why the system was designed the way it was you are unlikely to receive a satisfactory answer. This [answer](http://stackoverflow.com/questions/6722571/c-sharp-and-immutability-and-readonly-fields-a-lie) by Eric Lippert may be useful. – Mike Zboray Aug 11 '15 at 17:39
  • I guess I shouldn't say its purely a C# feature. The corresponding concept is the initonly attribute in CIL. However, the CLI specification makes it clear that the enforcement of the initonly contract is done by the entity that emits CIL, i.e. the C# compiler. – Mike Zboray Aug 11 '15 at 17:44
  • @mikez: Your comments and link shed a lot of light on this. It's interesting that this is not a CLR feature. I particularly like Erik Lippert's comments on fully trusted code. Thanks! – Will Custode Aug 11 '15 at 19:34

1 Answers1

1

A readonly field tells the compiler to prevent you from writing code that will mutate that value. If you use reflection you can bypass those checks and do basically whatever you want.

Note that is different from a const field, which is a compile time constant.

KirkSpaziani
  • 1,962
  • 12
  • 14
  • If one makes RONumber a property with only getter `public RONumber{get{return _roNumber;}}` I guess the setting method doesn't exist at all and then it would be harder to set the _roNumber. I can't remember all the flags for getting to the fields/properties/methods though so I might be mistaken. – LosManos Aug 11 '15 at 17:33