Assigning a value to an inherited readonly field?

Steffan Donal picture Steffan Donal · May 17, 2011 · Viewed 17.3k times · Source

So I have a base class that has many children. This base class defines some readonly properties and variables that have default values. These can be different, depending on the child.

Readonly properties/fields allow you to change the value of the variable inside the constructor and also the definition, but nowhere else. I get a 'readonly variable can only be assigned to in a constructor' error if I try to change the value of an inherited readonly variable in the child class' constructor. Why is this and how can I work around this, without Reflection?

My intention: To allow user extensibility through scripts where they can only change certain fields once.

Answer

Adam Houldsworth picture Adam Houldsworth · May 17, 2011

The reason is that you can only assign to readonly fields in the constructor of that class.
According to the definition of readonly in the C# Reference (emphasis mine):

When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.

To work around this, you could make a protected constructor in the base that takes a parameter for the readonly property.

An example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Base b = new Child();
            Console.WriteLine(b.i);
            Console.Read();
        }
    }

    class Base
    {
        public readonly int i;

        public Base()
        {
            i = 42;
        }

        protected Base(int newI)
        {
            i = newI;
        }
    }

    class Child : Base
    {
        public Child()
            : base(43)
        {}
    }
}