Reputation: 465
I have the following example:
public interface BaseCmd
{
object Content{get;set;}
}
public interface OverridedBaseCmd : BaseCmd
{
new object Content{get;}
}
So the idea here is to override the Content property into the new interface to have only the get.
If i try to use in code the content property it tells me to implement also the BaseCmd.Content property and obviously I don't want to do this. Any ideas how can I achieve this?
Regards!
Upvotes: 2
Views: 6144
Reputation: 1548
A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface.
public class ImplementCmd : OverridedBaseCmd
{
object content = null;
object OverridedBaseCmd.Content
{
get { return this.content; }
}
object BaseCmd.Content
{
get
{
return this.content;
}
set
{
this.content = value;
}
}
}
Explicit implementation is also used to resolve cases where two interfaces each declare different members of the same name such as a property and a method.
interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}
To implement both interfaces, a class has to use explicit implementation either for the property P, or the method P, or both.
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}
Upvotes: 0
Reputation: 4662
An interface is a contract and should not be thought of as inheritance where one "overrides" things. You are basically saying here that anything that implements OverridedBaseCmd should also implement BaseCmd. ie should have all the methods, properties etc as defined on the interfaces.
What would happen if someone calls the set of BaseCmd.Content of some class that implements BaseCmd but does not really since it was overridden by OverridedBaseCmd. This violates the concept that interfaces was created for and breaks the Liskov substitution of SOLID.
If you provide us with more info regarding what you are trying to accomplish we might suggest a better solution.
Upvotes: 4
Reputation: 672
Simple way:
object Content
{
get
{
// Your code here.
}
}
BaseCmd.Content
{
get
{
return this.Content;
}
set
{
throw new NotSupportedException();
}
}
But it is dangerous behavior and you should think about architecture of your application.
Upvotes: -1
Reputation: 33506
You can not.
If class X implements interface Y, then it must implement all methods/properties defined by it. And this includes all propget/propset/eventadd/eventremove methods.
If interface Z inherits from interface Y, then it includes all definitions from Y. There is no way of "removing" anything by inheritance. Simple and strict as it is.
Therefore, if Foo implements IZee which inherits from IBar, then it means that Foo implements both IZee and IBar, so must cover all things from both.
Moreover, there is no way of "removing" anything by class inheritance either. if you have class Foo inherit from Bar, and if class Foo defines new object Content
then the Foo still has original Content too. it is just hidden, but it is still there.
Last thing: if you really want to remove that "set", then it clearly shows that your OverridedBaseCmd
simply should not inherit from BaseCmd
. They define different things, they allow different ways of usage. They does not follow is-a nor Liskov's substitution rule.
If you really-really want to have it this way, you have to live with the extra unwanted methods. Leave them as Throw-NotImplementedException, and feel the pain later. Try to not think about leaving them "empty" and "doing nothing". This will be even more painful later.
Upvotes: 0
Reputation: 387567
You can’t do this.
If this worked, then an object implementing both (because you always implement every base type too) would provide only the getter when it’s a OverridedBaseCmd
, but would still provide (it would have to) the setter when cast as BaseCmd
:
OverridedBaseCmd a = someObj;
a.Content; // works
a.Content = "foo"; // does not work
BaseCmd b = a; // same object
b.Content = "bar"; // works now
The Liskov substitution principle disallows this. Whenever you have an object of type B, where B is a subtype of A, then you can also use that object in wherever place an object of type A is expected. So in your case, when something expects an object of type BaseCmd
—and as such has access to the setter—then giving it an object of type OverridedBaseCmd
will also have to work because OverridedBaseCmd
is a subtype of BaseCmd
.
Upvotes: 1