Assigning a value to an inherited readonly field?
You could get the exact behavior you are looking for by using virtual get only properties.
public class BSE
{
virtual public int Prop
{
get
{
return 6;
}
}
}
public class Derived : BSE
{
public override int Prop
{
get
{
return 10;
}
}
}
Fields are out side the inheritance and overloading model and should not be used to provide polymorphic features.
You can use property with public get accessor and protected set accessor. Derived classes can set value of this 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 int I { get; protected set; }
public Base()
{
I = 42;
}
}
class Child : Base
{
public Child()
{
I = 43;
}
}
}
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)
{}
}
}
Adam has the right answer. If you're worried about the space it will take up (number of parameters in the constructor?) then you should address that as a different problem with a different solution: create a BaseConfig class, that contains all those properties and that is all that needs to be passed in. Base can then either assign all it's readonly fields from BaseConfig's properties, or you can instead have Base hold just one readonly field of type BaseConfig and refer to that for the values.
As to why this is, see C# constructor execution order regarding when each class's readonly fields would be initialized/initializable.