Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

readonly-fields as targets from subclass constructors

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.

like image 242
philipshield Avatar asked Oct 09 '11 20:10

philipshield


People also ask

Can readonly be set in constructor?

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.

Can we modify readonly in C#?

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.

What is the purpose of readonly modifier?

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.

What is readonly property?

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.


3 Answers

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).

like image 193
m.edmondson Avatar answered Sep 23 '22 04:09

m.edmondson


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!

like image 28
Renato Gama Avatar answered Sep 25 '22 04:09

Renato Gama


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.

like image 44
Andreas Avatar answered Sep 24 '22 04:09

Andreas