TL;DR;
Overriding or implementing get-only property with settable property is prohibited in C#.
Partially correct. It's perfectly valid to implement a get-only property with a settable property - but it's invalid to override a get-only property with a settable property.
The long version:
When I've tried to compile your code, I've got two compilation errors (In VS 2017, if that matters)
Error CS0106 The modifier 'abstract' is not valid for this item
Error CS0106 The modifier 'public' is not valid for this item
When removed the public abstract
from the property in the interface, the code compiles just fine (removed the abstract class as it's irrelevant here):
public class Example : IExample
{
public int Property { get; set; }
}
public interface IExample
{
int Property { get; }
}
However, when attempting to use an abstract class and override a get only property with a get/set property, I got this compilation error:
Error CS0546 'Example.Property.set': cannot override because 'ExampleBase.Property' does not have an overridable set accessor
for the following code (removed the interface, same error for a private set):
public class Example : ExampleBase
{
public override int Property { get; set; }
}
public abstract class ExampleBase
{
public abstract int Property { get; }
}
This is actually a good way to show the difference between overriding and implementing in c#:
An interface is a contract. It force the implementing types to include it's members as a part of it's public API (explicit implementation aside). So when implementing an interface with a get-only property, you can add a setter to this property, because as long as it has the getter, the contract is still being fulfilled.
However, a base class is not a contract. If forces the inheriting classes to have the exact same member signature, but allows the inheriting class to override virtual members (so the same method or property will be implemented differently in the two classes). In fact, a derived class is a (specific) type of it's base class.
Usually If you want to add a setter to a get-only property in the base class, you will have to shadow it using the keyword new
, but this will not help with abstract members - an abstract member must be overriden in the derived class - and since we don't have properties overloads, you will have to add a method to set the value of the get-only property, and implement it explicitly:
public class Example : ExampleBase
{
private int _property;
public override int Property { get { return _property; } }
public void SetProperty(int property)
{
_property = property;
}
}
public abstract class ExampleBase
{
public abstract int Property { get; }
}
And for the sake of completeness - here is how you would use the new
keyword if the base property was not abstract:
public class Example : ExampleBase
{
public new int Property { get; set; }
}
public class ExampleBase
{
public virtual int Property { get; }
}