Override get, but not set - c#

I have an abstract class that defines a get, but not set, because as far as that abstract class is concerned, it needs only a get.
public abstract BaseClass
{
public abstract double MyPop
{get;}
}
However, in some of the derive class, I need a set property, so I am looking at this implementation
public class DClass: BaseClass
{
public override double MyPop
{get;set;}
}
The problem is, I got a compilation error, saying that
*.set: cannot override because *. does not have an overridable set accessor.
Even though I think that the above syntax is perfectly legitimate.
Any idea on this? Workaround, or why this is so?
Edit: The only approach I can think of is to put both get and set as in the abstract class, and let the subclass throws a NotImplementedException if set is called and it's not necessary. That's something I don't like, along with a special setter method .

One possible answer would be to override the getter, and then to implement a separate setter method. If you don't want the property setter to be defined in the base, you don't have many other options.
public override double MyPop
{
get { return _myPop; }
}
public void SetMyPop(double value)
{
_myPop = value;
}

New in C# 6.0:
If you are only calling the setter within your constructor, you can resolve this problem using read-only properties.
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;}
}

It is not possible to do what you want. You have to define the setter in the abstract property, otherwise you won't be able to override it properly.
The only case I know where a getter is defined and a getter/setter are implemented is by using an interface:
public interface IBaseInterface
{
double MyPop { get; }
}
public class DClass : IBaseInterface
{
public double MyPop { get; set; }
}

If BaseClass is in your own codebase, then you can do:
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; }
}
}
EDIT: You can then go make a public method in DClass SetMyProp(double myProp) or the like. The class design for your domain model should be clear about or speak for itself why you can't set the property directly in the base class and why you can do so in the derived one.

Are you sure that doing what you are trying to do would be a good design if you found a way to do it?
It would allow objects of the subclass to make state changes that objects of the parent class can not make. Wouldn't that violate the Liskov Substitution Principle?

You could do something like this:
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); }
}
}
Using TestDerived will have the functionality you're looking for. The only drawback I can see from this method is that you have to implement every abstract method in TestDerivedHelper, but it gives you more control later.
Hope this helps. ;)

The reason that this is not possible is due to the way parameters are "Magicked" into existence by C#. When you define a parameter, C# creates a private field that the implicit getter and setter manipulate. If there is no setter in the base class, it's impossible to change this variable from a method written in a sub class (as the private flag prohibits even sub classes from accessing it). What usually happens is it uses the implicit setter of the base class instead.
I wouldn't advise putting the set in the base class if not all sub classes can do it, because this goes against the whole principle of polymorphic programming (any abstract method defined in the abstract class must be implemented by a subclass). Creating a special setter method, as described in other answers is probably the best way go.

Siege
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); }
}
}
Using TestDerived will have the functionality you're looking for. The
only drawback I can see from this method is that you have to implement
every abstract method in TestDerivedHelper, but it gives you more
control later.
I use this approach and works very well for me.
Also, I made my "TestDerivedHelper" class abstract too, then all the methods must be implemented on "TestDerived" class.

Even though this thread is old I'm positing my solution, in case it helps someone. It is not my own but is based off answers in other SO topics.
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; } }
}
This solution adds an extra line of code for each such property that needs accessor modified. However, there is no change to external visibility and provides needed functionality.

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
}
If you need to set the property from outside DClass then maybe it would be better to put the setter into the base class.

EDIT:
OK I may have been hasty with this response, but I've given it some more thought now.
Do you have to use an abstract base class? If it's not required, try this:
public interface ISomeRelevantName
{
double MyPop { get; }
}
public class DClass : ISomeRelevantName
{
public double MyPop { get; set; }
}

Why not just have a property in the base class that has a private setter, then in your subclass that needs the setter, override it and make it public.

You cannot override the set accessor since the base class has no set accessor defined.
What you can do is use the new keyword to hide the base classes implementation, but that may not be what you want.

Related

Understanding polymorphism in general (c# example)

I am currently in the middle of self-teaching some basic concepts of C# and I am experimenting with abstract classes and polymorphism. I thought I got the basic concept but it turned out that the concept doesn't work like I understood it :). However - I hope I get some answers which clear the dust a little bit :).
The whole task I am trying to achieve is to extend an abstract base class and use the extension with an object of the base class. Like here:
I have an abstract class which implements an abstract property like:
public abstract class BaseClass
{
public abstract MyProperty mP{get;}
}
where the property is
public abstract class MyProperty
{
public abstract string PropertyName{get;}
}
Now I am deriving the MyProperty class for an actual implementation like
public class DerivedProperty : MyProperty
{
public override string PropertyName
{
get
{
return this._name;
}
}
private _name = "Property1";
/* some other implementation follows here...... */
}
As I've understood polymorphism and inheritance it should now be possible to instantiate a derived class from BaseClass and override the property MyProperty with an object of DerivedProperty like this:
public class DerivedClass : BaseClass
{
public override DerivedProperty mP
{
get
{
return dP;
}
}
private DerivedProperty dP = new DerivedProperty();
/* more implementation follows here...... */
}
Because DerivedProperty is an object of MyProperty and DerivedProperty at the same time it is possible to use it where either MyProperty or DerivedProperty is referenced. At least that's what I thought but it seems that this is wrong.
Now I am wondering - why is polymorphism so useful when something like above is not possible? Because even when I try something like this:
public class DerivedClass : BaseClass
{
public override MyProperty mP
{
get
{
return dP as DerivedProperty;
}
}
private DerivedProperty dP = new DerivedProperty();
/* more implementation follows here...... */
}
I still get only my base object MyProperty and not my extended object DerivedProperty which I want to get.
I know why I get those results - I just don't seem logical to me :). Is it really like polymorphism is supposed to work or is my implementation just crap and I have to do it in a different way to get my extended property?
Appreciate your help here!
You have to provide the same type for overrided property. You can use it later in your abstract BaseClass. Parameters as well as return value of member have to be the same when overriding. It is usually not a problem.
I've prepared following examples that my code look similar to yours.
In some scenarios I've seen that there is added second property with more specific type and different (more specific) name:
public abstract class BaseCar
{
public abstract BaseDriver Driver { get; }
}
public abstract class BaseDriver
{
public abstract string Name { get; set; }
}
public class AgressiveDriver : BaseDriver
{
public override string Name { get; set; }
}
public class FastCar : BaseCar
{
private AgressiveDriver _agressiveDriver = new AgressiveDriver();
public override BaseDriver Driver { get { return _agressiveDriver; } }
public AgressiveDriver AgressiveDriver { get { return _agressiveDriver; } }
}
Second approach is to use generics:
public abstract class BaseCar<TDriver>
where TDriver : BaseDriver
{
public abstract TDriver Driver { get; }
}
public abstract class BaseDriver
{
public abstract string Name { get; set; }
}
public class AgressiveDriver : BaseDriver
{
public override string Name { get; set; }
}
public class FastCar : BaseCar<AgressiveDriver>
{
private AgressiveDriver _agressiveDriver = new AgressiveDriver();
public override AgressiveDriver Driver { get { return _agressiveDriver; } }
}
but I think first approach is better because there is no problem with creating/using BaseCar objects (for example to create BaseCar<> variable you have to specify type parameter). Also it makes sense to create more specific name for more specific property.
I think you have an extra bit of complexity you don't need. You have an abstract class inside an abstract class. If you are just learning/relearning this you have skipped a couple easy steps for understanding. Here's a simpler example to start with.
public abstract class Shape
{
public abstract double GetArea();
public abstract double Circumference();
}
public class Square: Shape
{
public double width {get; set;}
public override double GetArea()
{
return width * width;
}
public override Circumference()
{
return width * 4;
}
}
You can now instantiate a Square or create a Circle Class and be able to use either where you use Shape.

How to automatically copy a property declaration to base class

I have a property A in all subclasses of base class Base.
How can I generate an abstract property definition of property A into base class Base?
I know ReSharper's refactoring Pull Members Up, but that moves the property to base class.
I need an abstract property in base class and a overriding properties in all sub classes. Is there a refactoring in Visual Studio or in ReSharper that can do it automatically for me?
There is a checkbox "Make abstract" for that in ReSharper Pull Members Up dialog :
I'm not sure Resharper can move up and create an abstraction as you want automatically, but you can atleast define it manually like this
In abstract class:
public abstract double A
{
get;
}
In Sub class:
public override double A
{
get
{
return 3.141;
}
}
It might be a clearner design to define a new Interface (or use an existing one) and define the property in the interface. That way, your existing subclasses won't have to use override.
public interface IInterface {
string MyProperty { get; }
}
public class Class : IInterface {
public string MyProperty { get; set; }
}
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;
}
}
I hope this will be helpful to you.

Can an interface require a property, but not specify a required type?

I have a simple interface, defined as such:
interface iFace
{
int Value { get; }
}
In this case, any class implementing iFace must have a property named Value of type int. The usage of this interface is going to be with databinding, and I don't care what type the property is. Do I have any options? I'd like to avoid this solution:
interface iFace<T>
{
T Value { get; }
}
as I'd like to refer to the interface without specifying type
Edit:
I'd like to be able able to apply the same interface to both a NumericUpDown control, and a Trackbar control. One's value property is of type decimal, and the other is of type int.
Having the property be of type object wouldn't work in this case.
If you don't care whether it is strictly-typed, change the property type to object.
Try this:
interface MyInterface
{
Object MyProperty
{
get;
set;
}
}
class MyClass : MyInterface
{
Object MyInterface.MyProperty
{
get
{
return this.MyProperty;
}
set
{
if (value is MyType)
this.MyProperty = (MyType)value;
}
}
public MyType MyProperty
{
get;
set;
}
}
In response to your edit: You're coming up against the well-known problem that .NET has no INumeric interface. It exists in source code I've seen, but it has been commented out, which implies that Microsoft has taken it seriously enough and run into some significant issues with it.
Danny Varod's solution is a good one; you can also extend it by creating a generic and a non-generic version of the interface. Another solution is to add methods to the interface that represent the numeric operations for which you're now using mathematical operators, like Increment(), for example.
I'll call the interface IHasValue here (partly because it is somewhat comedic):
interface IHasValue
{
object Value { get; set; }
void Increment();
void Decrement();
}
interface IHasValue<TValue> : IHasValue { new TValue Value { get; set; } }
abstract class UpDownValueControl<T> : IHasValue<T>
{
public T Value { get; set; }
object IHasValue.Value
{
get { return this.Value; }
set { this.Value = (T)value; }
}
public abstract void Increment();
public abstract void Decrement();
}
class NumericUpDownControl : UpDownValueControl<decimal>
{
public override void Increment() { Value++; }
public override void Decrement() { Value--; }
//rest of the implementation
}
class TrackbarControl : UpDownValueControl<int>
{
public override void Increment() { Value++; }
public override void Decrement() { Value--; }
//rest of the implementation
}
It's frustrating that the base class can't take care of repetitive code like the increment and decrement methods, but at least this approach allows the base class to take care of everything else aside from the repetitive mathematical operator code.
I suspect, in the end, that the complexity of this solution adds more cost than benefit; I think I'd be more likely to go with something like Danny Varod's solution.

Can the get of a property be abstract and the set be virtual?

I have a base class like this:
public class Trajectory{
public int Count { get; set; }
public double Initial { get; set { Count = 1; } }
public double Current { get; set { Count ++ ; } }
}
So, I have code in the base class, which makes the set-s virtual, but the get-s must stay abstract. So I need something like this:
...
public double Initial { abstract get; virtual set { Count = 1; } }
...
But this code gives an error.
The whole point is to implement the counter functionality in the base class instead in all the derived classes.
So, how can I make the get and set of a property with different modifiers?
split it into 2 functions:
public double Initial
{
get { return GetInitial(); }
set { SetInitial(value); }
}
protected virtual void SetInitial(double value)
{
Count = 1;
}
protected abstract double GetInitial();
Make it neither abstract nor virtual. And make the backing field private. That way, a derived class cannot override it nor can it mess with it.
No, you can't. At least I haven't found a solution.
If property is marked as abstract then neither it's getter and setter can have bodies.

Overriding fields or properties in subclasses

I have an abstract base class and I want to declare a field or a property that will have a different value in each class that inherits from this parent class.
I want to define it in the baseclass so I can reference it in a base class method - for example overriding ToString to say "This object is of type property/field".
I have got three ways that I can see of doing this, but I was wondering - what is the best or accepted way of doing this? Newbie question, sorry.
Option 1:
Use an abstract Property and override it on the inherited classes. This benefits from being enforced (you have to override it) and it is clean. But, it feels slightly wrong to return a hard-code value rather than encapsulate a field and it is a few lines of code instead of just. I also have to declare a body for "set" but that is less important (and there is probably a way to avoid that which I am not aware of).
abstract class Father
{
abstract public int MyInt { get; set;}
}
class Son : Father
{
public override int MyInt
{
get { return 1; }
set { }
}
}
Option 2
I can declare a public field (or a protected field) and explicitly override it in the inherited class. The example below will give me a warning to use "new" and I can probably do that, but it feels wrong and it breaks the polymorphism, which was the whole point. Doesn't seem like a good idea...
abstract class Mother
{
public int MyInt = 0;
}
class Daughter : Mother
{
public int MyInt = 1;
}
Option 3
I can use a protected field and set the value in the constructor. This seems pretty tidy but relies on me ensuring the constructor always sets this and with multiple overloaded constructors there is always a chance some code path won't set the value.
abstract class Aunt
{
protected int MyInt;
}
class Niece : Aunt
{
public Niece()
{
MyInt = 1;
}
}
It's a bit of a theoretical question and I guess the answer has to be option 1 as it is the only safe option but I am just getting to grips with C# and wanted to ask this of people with more experience.
Of the three solutions only Option 1 is polymorphic.
Fields by themselves cannot be overridden. Which is exactly why Option 2 returns the new keyword warning.
The solution to the warning is not to append the “new” keyword, but to implement Option 1.
If you need your field to be polymorphic you need to wrap it in a Property.
Option 3 is OK if you don’t need polymorphic behavior. You should remember though, that when at runtime the property MyInt is accessed, the derived class has no control on the value returned. The base class by itself is capable of returning this value.
This is how a truly polymorphic implementation of your property might look, allowing the derived classes to be in control.
abstract class Parent
{
abstract public int MyInt { get; }
}
class Father : Parent
{
public override int MyInt
{
get { /* Apply formula "X" and return a value */ }
}
}
class Mother : Parent
{
public override int MyInt
{
get { /* Apply formula "Y" and return a value */ }
}
}
Option 2 is a non-starter - you can't override fields, you can only hide them.
Personally, I'd go for option 1 every time. I try to keep fields private at all times. That's if you really need to be able to override the property at all, of course. Another option is to have a read-only property in the base class which is set from a constructor parameter:
abstract class Mother
{
private readonly int myInt;
public int MyInt { get { return myInt; } }
protected Mother(int myInt)
{
this.myInt = myInt;
}
}
class Daughter : Mother
{
public Daughter() : base(1)
{
}
}
That's probably the most appropriate approach if the value doesn't change over the lifetime of the instance.
You could do this
class x
{
private int _myInt;
public virtual int myInt { get { return _myInt; } set { _myInt = value; } }
}
class y : x
{
private int _myYInt;
public override int myInt { get { return _myYInt; } set { _myYInt = value; } }
}
virtual lets you get a property a body that does something and still lets sub-classes override it.
option 2 is a bad idea. It will result in something called shadowing; Basically you have two different "MyInt" members, one in the mother, and the other in the daughter. The problem with this, is that methods that are implemented in the mother will reference the mother's "MyInt" while methods implemented in the daughter will reference the daughter's "MyInt". this can cause some serious readability issues, and confusion later down the line.
Personally, I think the best option is 3; because it provides a clear centralized value, and can be referenced internally by children without the hassle of defining their own fields -- which is the problem with option 1.
You could define something like this:
abstract class Father
{
//Do you need it public?
protected readonly int MyInt;
}
class Son : Father
{
public Son()
{
MyInt = 1;
}
}
By setting the value as readonly, it ensures that the value for that class remains unchanged for the lifetime of the object.
I suppose the next question is: why do you need it?
If you are building a class and you want there to be a base value for the property, then use the virtual keyword in the base class. This allows you to optionally override the property.
Using your example above:
//you may want to also use interfaces.
interface IFather
{
int MyInt { get; set; }
}
public class Father : IFather
{
//defaulting the value of this property to 1
private int myInt = 1;
public virtual int MyInt
{
get { return myInt; }
set { myInt = value; }
}
}
public class Son : Father
{
public override int MyInt
{
get {
//demonstrating that you can access base.properties
//this will return 1 from the base class
int baseInt = base.MyInt;
//add 1 and return new value
return baseInt + 1;
}
set
{
//sets the value of the property
base.MyInt = value;
}
}
}
In a program:
Son son = new Son();
//son.MyInt will equal 2
You can go with option 3 if you modify your abstract base class to require the property value in the constructor, you won't miss any paths. I'd really consider this option.
abstract class Aunt
{
protected int MyInt;
protected Aunt(int myInt)
{
MyInt = myInt;
}
}
Of course, you then still have the option of making the field private and then, depending on the need, exposing a protected or public property getter.
I'd go with option 3, but have an abstract setMyInt method that subclasses are forced to implement. This way you won't have the problem of a derived class forgetting to set it in the constructor.
abstract class Base
{
protected int myInt;
protected abstract void setMyInt();
}
class Derived : Base
{
override protected void setMyInt()
{
myInt = 3;
}
}
By the way, with option one, if you don't specify set; in your abstract base class property, the derived class won't have to implement it.
abstract class Father
{
abstract public int MyInt { get; }
}
class Son : Father
{
public override int MyInt
{
get { return 1; }
}
}
I did this...
namespace Core.Text.Menus
{
public abstract class AbstractBaseClass
{
public string SELECT_MODEL;
public string BROWSE_RECORDS;
public string SETUP;
}
}
namespace Core.Text.Menus
{
public class English : AbstractBaseClass
{
public English()
{
base.SELECT_MODEL = "Select Model";
base.BROWSE_RECORDS = "Browse Measurements";
base.SETUP = "Setup Instrument";
}
}
}
This way you can still use fields.
The example implementation when you want to have an abstract class with implementation. Subclasses must:
Parameterize the implementation of an abstract class.
Fully inherit the implementation of the abstract class;
Have your own implementation.
In this case, the properties that are necessary for the implementation should not be available for use except for the abstract class and its own subclass.
internal abstract class AbstractClass
{
//Properties for parameterization from concrete class
protected abstract string Param1 { get; }
protected abstract string Param2 { get; }
//Internal fields need for manage state of object
private string var1;
private string var2;
internal AbstractClass(string _var1, string _var2)
{
this.var1 = _var1;
this.var2 = _var2;
}
internal void CalcResult()
{
//The result calculation uses Param1, Param2, var1, var2;
}
}
internal class ConcreteClassFirst : AbstractClass
{
private string param1;
private string param2;
protected override string Param1 { get { return param1; } }
protected override string Param2 { get { return param2; } }
public ConcreteClassFirst(string _var1, string _var2) : base(_var1, _var2) { }
internal void CalcParams()
{
//The calculation param1 and param2
}
}
internal class ConcreteClassSecond : AbstractClass
{
private string param1;
private string param2;
protected override string Param1 { get { return param1; } }
protected override string Param2 { get { return param2; } }
public ConcreteClassSecond(string _var1, string _var2) : base(_var1, _var2) { }
internal void CalcParams()
{
//The calculation param1 and param2
}
}
static void Main(string[] args)
{
string var1_1 = "val1_1";
string var1_2 = "val1_2";
ConcreteClassFirst concreteClassFirst = new ConcreteClassFirst(var1_1, var1_2);
concreteClassFirst.CalcParams();
concreteClassFirst.CalcResult();
string var2_1 = "val2_1";
string var2_2 = "val2_2";
ConcreteClassSecond concreteClassSecond = new ConcreteClassSecond(var2_1, var2_2);
concreteClassSecond.CalcParams();
concreteClassSecond.CalcResult();
//Param1 and Param2 are not visible in main method
}

Categories