I'm trying to create an abstract class that defines a property with a getter. I want to leave it up to derived classes to decide if they want to implement a setter for the property or not. Is this possible?
What I have so far:
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;
}
}
In ConcreteClass1
, I get an error on the set
. It can't override set_Value
because no overridable set accessor exists in AbstractClass.
In ConcreteClass2
, I get an error on both Value
's because a member with the same name is already declared.
ConcreteClass3
doesn't give an error, but even though Value's set accessor would be compiled into set_Value, it doesn't work the other way around. Defining a set_Value
does not mean that Value
gets a set accessor. So I can't assign a value to a ConcreteClass3.Value property. I can use ConcreteClass3.set_Value("value"), but that's not what I'm trying to achieve here.
Is it possible to have the abstract class demand a public getter, while allowing an optional setter to be defined in a derived class?
In case you'r wondering, this is just a theoretical question. I don't have a real situation where something like this is needed. But I can imagine an abstract class that doesn't care how a property gets set, but that does need to be able to get the property.
An abstract property declaration does not provide an implementation of the property accessors -- it declares that the class supports properties, but leaves the accessor implementation to derived classes. The following example demonstrates how to implement the abstract properties inherited from a base class.
Abstract classes have the following features: An abstract class cannot be instantiated. An abstract class may contain abstract methods and accessors. It is not possible to modify an abstract class with the sealed modifier because the two modifiers have opposite meanings.
An abstract method cannot be private as in the following, abstract class Demo() { private abstract void Call();
C# Abstract Class Features An abstract class can implement code with non-Abstract methods. An Abstract class can have modifiers for methods, properties etc. An Abstract class can have constants and fields.
Unfortunately, you can't do exactly what you want. You can do this with interfaces though:
public interface IInterface {
string MyProperty { get; }
}
public class Class : IInterface {
public string MyProperty { get; set; }
}
The way I would do it is to have a separate SetProperty method in the concrete classes:
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;
}
}
Found a solution: How to override a getter-only property with a setter in 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
is now equivalent to a class inheriting from B
while also being able to override in a setter.
You can just use protected
access modifier instead. Because of inheritance you are not allowed to use private
. It looks like so:
public abstract class A
{
public abstract int prop { get; protected set; }
}
public abstract class B : A
{
public override int prop { get; protected set; }
}
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