I have an interface that declares some properties (shortened to Id
only in the example) with only a get
method. Classes implementing this interface do not have to provide a public setter for this property:
public interface IMetadataColumns
{
Int32 Id { get; }
}
Now I need another interface with the same properties, but now they must all be writable as well. So I added a new interface inheriting from the old one where each property also has a setter:
public interface IMetadataColumnsWritable : IMetadataColumns
{
Int32 Id { get; set; }
}
Visual Studio now underlines this and warns me to use the new
keyword if hiding the old properties was intended.
What shall I do now? I have classes implementing the IMetadataColumns
interface which need some of the properties to be read-only, but I also have other classes where exactly those same properties must be writable as well.
I guess hiding a property sounds somehow not like the way to go...
When interfaces are involved, the new
keyword doesn't mean you are hiding the property in the same sense as with classes.
Your class implementing IMetadataColumnsWritable
will only have one Id
, regardless of whether you cast it to the base IMetadataColumns
interface or not (unless you add an explicit implementation for the readonly property - but this is not needed and would only allow for errors in this case).
In other words, you might have:
// this interface is public, and it allows everyone to read the Id
public interface IMetadataColumns
{
int Id { get; }
}
// this one is writeable, but it's internal
internal interface IMetadataColumnsWritable : IMetadataColumns
{
// we need to use 'new' here, but this doesn't mean
// you will end up with two getters
new int Id { get; set; }
}
// internal implementation is writeable, but you can pass it
// to other assemblies through the readonly IMetadataColumns
// interface
internal class MetadataColumns : IMetadataColumnsWritable
{
public int Id { get; set; }
}
So, unless you explicitly implement the readonly property as a separate one, you will have only a single property, whichever interface you use to access it:
var columns = new MetadataColumns { Id = 5 };
var x = (columns as IMetadataColumns).Id;
var y = (columns as IMetadataColumnsWritable).Id;
Debug.Assert(x == y);
Hiding a member inside the class using the new
keyword, on the other hand, is what I would not recommend in most cases, because it basically creates a completely new member, which just happens to be called the same as a different member in the base class.
You should indeed use the new
keyword here. In your class implementation, you have to implement both properties (since you are not really hiding the property). If they have different return types, at least one of them has to be implemented explicitly.
public class X : IMetadataColumnsWritable
{
public int Id
{
get;
set;
}
// only necessary if you have to differentiate on the implementation.
int IMetadataColumns.Id
{
get
{
return this.Id; // this will call the public `Id` property
}
}
}
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