A readonly field should be used when you have a variable that will be known at object-instatiation which should not be changed afterwards.
However one is not allowed to assign readonly fields from constructors of subclasses. This doesn't even work if the superclass is abstract.
Does anyone have a good explanation why this either isn't a good idea, or lacks in the C# languange?
abstract class Super
{
protected readonly int Field;
}
class Sub : Super
{
public Sub()
{
this.Field = 5; //Not compileable
}
}
PS: You can of course reach the same result by having assignment of the readonly fields in a protected constructor in the superclass.
In a field declaration, readonly indicates that assignment to the field can only occur as part of the declaration or in a constructor in the same class. A readonly field can be assigned and reassigned multiple times within the field declaration and constructor.
Use the readonly keyword in C# This means that the variable or object can be assigned a value at the class scope or in a constructor only. You cannot change the value or reassign a value to a readonly variable or object in any other method except the constructor.
Readonly Fields: In C#, you are allowed to declare a field using readonly modifier. It indicates that the assignment to the fields is only the part of the declaration or in a constructor to the same class.
A class property declared read-only is only allowed to be initialized once, and further changes to the property is not allowed. Read-only class properties are declared with the readonly keyword* in a typed property.
The only reason I can see for this is because "it was just designed that way", as per the spec:
Direct assignments to readonly fields can only occur as part of that declaration or in an instance constructor or static constructor in the same class.
The point of being read only is that it cannot be changed, if derived classes could modify then this would no longer be true and will violate encapsulation (by modifying the internals of another class).
public class Father
{
protected readonly Int32 field;
protected Father (Int32 field)
{
this.field = field;
}
}
public class Son : Father
{
public Son() : base(5)
{
}
}
You may try something like this instead!
I would model this by an abstract/virtual property in C#.
abstract class Super {
protected abstract int Field { get; }
}
class Sub : Super {
protected override int Field { get { return 5; } }
}
In my opinion that's a better solution than to have a constructor that includes each and every readonly field as parameter. For one because the compiler is able to inline this as well and also because the constructor solution will look like this in the derived class:
class Sub : Super {
public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor
}
Also that may not work if you already have a constructor that takes a single int value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With