Why is it that the following is legal C#:
public interface ISomeInterface
{
int SomeProperty
{
get;
}
}
public class SomeClassImplementingInterface : ISomeInterface
{
public int SomeProperty
{
get { return 32; }
protected set {}
}
}
but this is not:
public abstract class SomeAbstractClass
{
public abstract int SomeProperty
{
get;
}
}
public class SomeClassExtendingAbstractClass : SomeAbstractClass
{
public override int SomeProperty
{
get { return 32; }
protected set {}
}
}
The latter results in the following compile-time error:
'InterfaceAbstractTest.SomeClassExtendingAbstractClass.SomeProperty.set': cannot override because 'InterfaceAbstractTest.SomeAbstractClass.SomeProperty' does not have an overridable set accessor InterfaceAbstractTest
What is the reasoning for not disallowing the latter whilst allowing the former?
Because a caller using the interface only cares that an implementer of the interface at least implements the interface's definition, as @davisoa states, whereas SomeAbstractClass
in your example defines a public contract which states exactly the type, accessibility, and (for properties) readability/writability of members.
If you use reflection to get the PropertyInfo of SomeProperty
(from either the base or child class), it needs to resolve that information from somewhere. Allowing the child class to change the readability/writability would be as much of a contract violation as a change in return type or argument list.
Imagine for instance:
SomeAbstractClass sc = new SomeClassExtendingAbstractClass();
PropertyInfo pi = sc.GetType().GetProperty("SomeProperty");
Console.Out.WriteLine(pi.CanWrite); // What should be printed here?
This is because the Interface implementation is making a promise that there will be a property SomeProperty
that you can "Get".
The abstract class implementation is making a promise that it's child classes will provide an implementation of a property SomeProperty
with a public get method.
In the end, the base class is defining something that must be overridden, whereas the interface is defining a contract.
This is by design. I am quoting from the C# language specs:
An overriding property declaration must specify the exact same accessibility modifiers, types and name as the inherited property, if the inherited property has only a single accessor (i.e.,... ready only or write-only), the overriding property must include only that accessor.
The reason behind that decesion could be because the interfaces are more flexibly type of contracts than abstract classes. Interfaces cares only about the least common denominator rather than the whole implementation. I think there are good reasons to choose one design over the other.
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