views:

315

answers:

2

I would like to only force the implementation of a C# getter on a given property from a base abstract class. Derived classes might, if they want, also provide a setter for that property for public use of the statically bound type.

Given the following abstract class:

public abstract class Base
{
    public abstract int Property { get; }
}

If I want a derived class that also implements a setter, I could naively try:

public class Derived : Base
{
    public override int Property
    {
        get { return field; }
        set { field = value; } // Error : Nothing to override.
    } 

    private int field;
}

But then I get a syntax error since I try to override the non existing setter. I tried some other way such as declaring the base setter private and such and I still stumble upon all kind of errors preventing me from doing that. There must be a way to do that as it doesn't break any base class contract.

Incidentaly, it can be done with interfaces, but I really need that default implementation.

I stumbled into that situation so often, I was wondering if there was a hidden C# syntax trick to do that, else I will just live with it and implement a manual SetProperty() method.

+1  A: 

You can't do it directly, since you can't new and override with the same signature on the same type; there are two options - if you control the base class, add a second property:

public abstract class Base
{
    public int Property { get { return PropertyImpl; } }
    protected abstract int PropertyImpl {get;}
}
public class Derived : Base
{
    public new int Property {get;set;}
    protected override int PropertyImpl
    {
        get { return Property; }
    }
}

Else you can introduce an extra level in the class hierarchy:

public abstract class Base
{
    public abstract int Property { get; }
}
public abstract class SecondBase : Base
{
    public sealed override int Property
    {
        get { return PropertyImpl; }
    }
    protected abstract int PropertyImpl { get; }
}
public class Derived : SecondBase
{
    public new int Property { get; set; }

    protected override int PropertyImpl
    {
        get { return Property; }
    }
}
Marc Gravell
Your solutions are interesting, I will ponder a little on them.
Coincoin
Your solution is what is the closest to the thing. But I don't think it's possible to do it without forcing the derived class to do acrobatics.
Coincoin
+1  A: 

What about something like:

public abstract class Base
{
    public virtual int Property
    {
        get { return this.GetProperty(); }
        set { }
    }

    protected abstract int GetProperty();
}
Rex M
Any inheritor now has to override both of them - a bit redundant?
Marc Gravell
Only if overriding the property. Else, without the virtual property that could actually be an acceptable alternative.
Coincoin
If you don't override the property, the purpose of the set is very... unusual.
Marc Gravell
You are right, I totally misread the answer. It has to be newed somewhere.
Coincoin
@Marc as far as I can tell it accomplishes the requirement, with the only caveat that adding a setter requires also a getter which just calls base.
Rex M
It's a tie but I chose the other answer because I don't feel at ease with the empty setter in the base class. However, I don't think there is a perfectly good answer.
Coincoin