Override abstract readonly property to read/write property

Coincoin picture Coincoin · Sep 28, 2009 · Viewed 14.2k times · Source

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.

Answer

Marc Gravell picture Marc Gravell · Sep 28, 2009

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; }
    }
}