usar una sirve sellada que protegido para nuevo miembro metodos interfaces español ejercicios ejemplos declarado clases clase caracteristicas abstractas abstracta c# properties abstract-class setter getter

c# - una - Propiedad abstracta con captador público, definir setter privado en clase concreta posible?



sealed class c# español (3)

Estoy tratando de crear una clase abstracta que define una propiedad con un captador. Quiero dejarlo en clases derivadas para decidir si quieren implementar un establecedor para la propiedad o no. es posible?

Lo que tengo hasta ahora:

public abstract class AbstractClass { public abstract string Value { get; } public void DoSomething() { Console.WriteLine(Value); } } public class ConcreteClass1 : AbstractClass { public override string Value { get; set; } } public class ConcreteClass2 : AbstractClass { private string _value; public override string Value { get { return _value; } } public string Value { set { _value = value; } } } public class ConcreteClass3 : AbstractClass { private string _value; public override string Value { get { return _value; } } public void set_Value(string value) { _value = value; } }

En ConcreteClass1 , me sale un error en el set . No puede anular set_Value porque no existe ningún descriptor de set_Value reemplazable en AbstractClass.

En ConcreteClass2 , recibo un error en ambos Value porque un miembro con el mismo nombre ya está declarado.

ConcreteClass3 no da un error, pero a pesar de que el conjunto de elementos de acceso de Value se compilaría en set_Value, no funcionará al revés. Definir un valor de set_Value no significa que el Value obtenga un acceso al conjunto. Así que no puedo asignar un valor a una propiedad ConcreteClass3.Value. Puedo usar ConcreteClass3.set_Value ("valor"), pero eso no es lo que estoy tratando de lograr aquí.

¿Es posible que la clase abstracta exija un captador público, mientras permite que un definidor opcional se defina en una clase derivada?

En caso de que se lo pregunte, esta es solo una pregunta teórica. No tengo una situación real donde se necesite algo como esto. Pero puedo imaginar una clase abstracta a la que no le importa cómo se establece una propiedad, pero que sí necesita poder obtenerla.


Desafortunadamente, no puedes hacer exactamente lo que quieres. Puedes hacer esto con interfaces sin embargo:

public interface IInterface { string MyProperty { get; } } public class Class : IInterface { public string MyProperty { get; set; } }

La forma en que lo haría es tener un método SetProperty separado en las clases concretas:

public abstract class AbstractClass { public abstract string Value { get; } } public class ConcreteClass : AbstractClass { private string m_Value; public override string Value { get { return m_Value; } } public void SetValue(string value) { m_Value = value; } }


Encontró una solución: ¿Cómo anular una propiedad solo para captadores con un configurador en C #?

public abstract class A { public abstract int X { get; } } public class B : A { public override int X { get { return 0; } } } /*public class C : B //won''t compile: can''t override with setter { private int _x; public override int X { get { return _x; } set { _x = value; } } }*/ public abstract class C : B //abstract intermediate layer { public sealed override int X { get { return this.XGetter; } } protected abstract int XGetter { get; } } public class D : C //does same thing, but will compile { private int _x; protected sealed override int XGetter { get { return this.X; } } public new virtual int X { get { return this._x; } set { this._x = value; } } }

D ahora es equivalente a una clase heredada de B y también puede anular en un configurador.


No muy elegante, pero es lo más cerca que puede estar sin hacer algo como lo que hizo en concreto3

public class Concrete : AbstractClass { public new void DoSomething() { Console.WriteLine(Value); } } public abstract class AbstractClass { protected AbstractClass() { try { var value = Value; } catch (NotImplementedException) { throw new Exception("Value''s getter must be overriden in base class"); } } public void DoSomething() { Console.WriteLine(Value); } /// <summary> /// Must be override in subclass /// </summary> public string Value { get { throw new NotImplementedException(); } } }