In my project I've found a strange situation which seems completely valid in C#, because I have no compilte-time errors.
Simplified example looks like that:
using System; using System.Collections.Generic; namespace Test { interface IFoo { void FooMethod(); } class A { public void FooMethod() { Console.WriteLine("implementation"); } } class B : A, IFoo { } class Program { static void Main(string[] args) { IFoo foo = new B(); foo.FooMethod(); } } }
Such code compiles. However, note that A
is not IFoo
and B
doesn't implement IFoo
methods. In my case, by accident (after refactoring), A
has the method with the same signature. But why should A
know how to implement the FooMethod
of the IFoo
interface? A
even doesn't know that IFoo
exist.
For me having such design is dangerous. Because every time I implement some interface I should check if each method in this interface "interferes" with the base class methods.
If this is "pure C# feature"? What is it called? Am I missing something?
A base class can also implement interface members by using virtual members. In that case, a derived class can change the interface behavior by overriding the virtual members.
A class implementation of a method takes precedence over a default method. So, if the class already has the same method as an Interface, then the default method from the implemented Interface does not take effect. However, if two interfaces implement the same default method, then there is a conflict.
C# allows that a single class can implement multiple interfaces at a time, and also define methods and variables in that interface.
No, its an errorIf two interfaces contain a method with the same signature but different return types, then it is impossible to implement both the interface simultaneously.
Adding a method to an interface is equivalent to adding an abstract method to a base class; any class that implements the interface will break because the class does not implement the new method. Interfaces are appropriate in the following situations: Several unrelated classes want to support the protocol.
There's also the Open/Closed principle. If you can inherit, great, but you don't want to have to go back and change the base class (and risk breaking other stuff) because it's needed for a new inherited class to work right. Programming to an interface instead of a base class can protect you from having to modify existing base classes.
} } The derived class doesn't directly implement the interface itself, it merely inherits the interface implementation from its base class (and then chooses to override it, but that's not a requirement, it could choose to keep the base method as is).
In Python for example, the distinction is made clear between a Class, which declares that it implements an interface, and an object, which is an instance of a class, and is said to provide that interface.
For each member in the interface, the compiler simply looks for an explicit implementation (if one), then a public implementation (implicit implementation), i.e. a method on the public API that matches the interface signature. In this case, A.FooMethod()
looks like a fine match for a public implementation. If B
wasn't happy with that selection, it could either new
the method, or use an explicit implementation; the latter would be preferred:
void IFoo.FooMethod() { /* explicit implementation */ }
The key word here is implements
. Your base class, although it doesn't know anything about IFoo
the method signature has been declared which implements the method in your interface somewhere in your class hierarchy.
So when you implement IFoo
in the derived class, it already has the method signature implemented within the class structure so therefore doesn't need to implement it again.
If you had this:
interface IFoo { void FooMethod(); } class A { private void FooMethod(){} } class B : A, IFoo { }
You need to implement IFoo
in this case because the IFoo
structure isn't accessible at the point where it is implemented, and as Mark says. You can implicitly implement the interface by doing IFoo.FooMethod()
to ensure that you have an implementation despite having an appropriate method signature already defined in the hierarchy.
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