remarks method generate c#

method - remarks c#



Anular obtener, pero no establecer (13)

Tengo una clase abstracta que define un get , pero no un set , porque en lo que respecta a esa clase abstracta, solo necesita un get .

public abstract BaseClass { public abstract double MyPop {get;} }

Sin embargo, en algunas de las clases derivadas, necesito una propiedad set , así que estoy viendo esta implementación

public class DClass: BaseClass { public override double MyPop {get;set;} }

El problema es que obtuve un error de compilación, diciendo que

* .set: no puede anular porque *. no tiene un acceso de conjunto invalidable.

Aunque creo que la sintaxis anterior es perfectamente legítima.

Alguna idea sobre esto? ¿Solución temporal, o por qué es así?

Editar: El único enfoque que se me ocurre es poner tanto get como set en la clase abstracta, y dejar que la subclase arroje una NotImplementedException si se llama a set y no es necesario. Eso es algo que no me gusta, junto con un método especial de establecimiento .


¿Estás seguro de que hacer lo que estás tratando de hacer sería un buen diseño si encuentras una forma de hacerlo?

Permitiría a los objetos de la subclase hacer cambios de estado que los objetos de la clase padre no pueden realizar. ¿No violaría eso el Principio de Sustitución de Liskov?


¿Por qué no solo tener una propiedad en la clase base que tiene un colocador privado, luego en su subclase que necesita el colocador, anularlo y hacerlo público?


Aunque este hilo es viejo, estoy planteando mi solución, en caso de que ayude a alguien. No es mío, pero se basa en respuestas en otros temas SO.

public abstract BaseClass { public double MyPoP { get { return GetMyPoP; } } protected abstract double GetMyPoP { get; } } public class DClass: BaseClass { public new double MyPoP { get; set; } protected override double GetMyPop { get { return MyPoP; } } }

Esta solución agrega una línea adicional de código para cada propiedad que necesita acceso o modificación. Sin embargo, no hay cambios en la visibilidad externa y proporciona la funcionalidad necesaria.


Cerco

abstract class TestBase { public abstract int Int { get; } } class TestDerivedHelper : TestBase { private int _Int; public override int Int { get { return _Int; } } protected void SetInt(int value) { this._Int = value; } } class TestDerived : TestDerivedHelper { public new int Int { get { return base.Int; } set { base.SetInt(value); } } }

El uso de TestDerived tendrá la funcionalidad que estás buscando. El único inconveniente que puedo ver de este método es que debe implementar todos los métodos abstractos en TestDerivedHelper, pero le da más control más adelante.

Utilizo este enfoque y me funciona muy bien. Además, hice mi resumen de la clase "TestDerivedHelper" también, luego todos los métodos deben implementarse en la clase "TestDerived".


EDITAR:

De acuerdo, es posible que me haya apresurado con esta respuesta, pero ya lo pensé un poco más.

¿Tienes que usar una clase base abstracta? Si no es necesario, intente esto:

public interface ISomeRelevantName { double MyPop { get; } } public class DClass : ISomeRelevantName { public double MyPop { get; set; } }


La razón por la que esto no es posible se debe a la forma en que los parámetros son "Magicked" a la existencia por C #. Cuando define un parámetro, C # crea un campo privado que manipulan el eliminador y el colocador implícitos. Si no hay un setter en la clase base, es imposible cambiar esta variable desde un método escrito en una subclase (ya que la bandera privada prohíbe que incluso las subclases accedan a ella). Lo que generalmente sucede es que usa el setter implícito de la clase base en su lugar.

No aconsejaría poner el conjunto en la clase base si no todas las subclases pueden hacerlo, porque esto va en contra de todo el principio de la programación polimórfica (cualquier método abstracto definido en la clase abstracta debe ser implementado por una subclase). Crear un método setter especial, como se describe en otras respuestas es probablemente la mejor manera de ir.


No es posible hacer lo que quieres. Debe definir el colocador en la propiedad abstracta; de lo contrario, no podrá sobrescribirlo correctamente.

El único caso que conozco donde se define un getter y se implementa un getter / setter es mediante el uso de una interfaz:

public interface IBaseInterface { double MyPop { get; } } public class DClass : IBaseInterface { public double MyPop { get; set; } }


No puede anular el acceso del conjunto ya que la clase base no tiene un acceso de acceso definido.

Lo que puede hacer es usar la new palabra clave para ocultar la implementación de las clases base, pero eso puede no ser lo que quiere.


Nuevo en C # 6.0:

Si solo llama al colocador dentro de su constructor, puede resolver este problema utilizando propiedades de solo lectura.

void Main() { BaseClass demo = new DClass(3.6); } public abstract class BaseClass { public abstract double MyPop{ get; } } public class DClass : BaseClass { public override double MyPop { get; } public DClass(double myPop) { MyPop = myPop;} }


Podrías hacer algo como esto:

abstract class TestBase { public abstract int Int { get; } }

class TestDerivedHelper : TestBase { private int _Int; public override int Int { get { return _Int; } } protected void SetInt(int value) { this._Int = value; } } class TestDerived : TestDerivedHelper { public new int Int { get { return base.Int; } set { base.SetInt(value); } } }

El uso de TestDerived tendrá la funcionalidad que estás buscando. El único inconveniente que puedo ver de este método es que debe implementar todos los métodos abstractos en TestDerivedHelper, pero le da más control más adelante.

Espero que esto ayude. ;)


Si BaseClass está en su propia base de código, entonces puede hacer:

abstract public class BaseClass { abstract public double MyPop { get; protected set; } } public class DClass : BaseClass { private double _myProp; public override double MyProp { get { return _myProp; } protected set { _myProp = value; } } }

EDITAR: Luego puede ir a hacer un método público en DClass SetMyProp(double myProp) o similar. El diseño de clase para su modelo de dominio debe ser claro o hablar por sí mismo por qué no puede establecer la propiedad directamente en la clase base y por qué puede hacerlo en la derivada.


Una posible respuesta sería anular el captador, y luego implementar un método setter separado. Si no desea que el establecimiento de propiedades se defina en la base, no tiene muchas otras opciones.

public override double MyPop { get { return _myPop; } } public void SetMyPop(double value) { _myPop = value; }


public abstract class BaseClass { public abstract double MyPop { get; } } public class DClass: BaseClass { private double _myPop = 0; public override double MyPop { get { return _myPop; } } // some other methods here that use the _myPop field }

Si necesita establecer la propiedad desde fuera de DClass entonces tal vez sería mejor colocar al colocador en la clase base.