subclase - propiedades en c#
campos de solo lectura como objetivos de constructores de subclases (5)
La única razón por la que puedo ver esto es porque "fue diseñado de esa manera", según la spec :
Las asignaciones directas a campos de solo lectura solo pueden ocurrir como parte de esa declaración o en un constructor de instancia o constructor estático en la misma clase.
El punto de ser solo de lectura es que no se puede cambiar, si las clases derivadas pudieran modificarse, esto ya no sería cierto y violaría la encapsulación (al modificar las partes internas de otra clase).
Se debe usar un campo de solo lectura cuando tenga una variable que se conocerá en la creación de objetos y que no se debe cambiar después.
Sin embargo, no se permite asignar campos de solo lectura de los constructores de subclases. Esto ni siquiera funciona si la superclase es abstracta.
¿Alguien tiene una buena explicación de por qué esto no es una buena idea o carece del lenguaje C #?
abstract class Super
{
protected readonly int Field;
}
class Sub : Super
{
public Sub()
{
this.Field = 5; //Not compileable
}
}
PD: Por supuesto, puede alcanzar el mismo resultado asignando los campos de solo lectura en un constructor protegido en la superclase.
Preferiría usar el constructor protegido en superclase (como lo mencionó alexm), a la vez con comentarios xml. Esto debería eliminar el problema que dijo DonAndre en su comentario de código.
Supongo que la razón principal es una complejidad adicional para todas las implementaciones de lenguaje .NET
También, siempre hay una solución simple:
abstract class Super
{
protected readonly int Field;
protected Super(int field)
{
this.Field = field;
}
}
class Sub : Super {
public Sub():base(5)
{
}
}
Yo modelaría esto por una propiedad abstracta / virtual en C #.
abstract class Super {
protected abstract int Field { get; }
}
class Sub : Super {
protected override int Field { get { return 5; } }
}
En mi opinión, es una solución mejor que tener un constructor que incluya todos y cada uno de los campos de lectura como parámetro. Por un lado, porque el compilador también puede alinear esto y también porque la solución del constructor se verá así en la clase derivada:
class Sub : Super {
public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor
}
Además, puede que no funcione si ya tienes un constructor que toma un solo valor int.
public class Father
{
protected readonly Int32 field;
protected Father (Int32 field)
{
this.field = field;
}
}
public class Son : Father
{
public Son() : base(5)
{
}
}
¡Puedes probar algo como esto en su lugar!