Why is it possible to implement an interface method in base class?

C#Interface

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

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 */ }

Solution 2 - C#

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.

Solution 3 - C#

You say in a comment,

> how likely that the one who wrote implementation of FooMethod in A class which doesn't implement IFoo actually meant to implement IFoo?

Well, it doesn't matter what the writer of A thought at the time of A's creation. It's the writer of B who must take responsibility for the fact that B both inherits from A AND implements IFoo. It is up to the author of B to think about the consequences of the definition of B.

You also say

> In my case by accident (after refactoring) A has the method with the same signature

suggesting that this situation came about after A and B had both been written. In that case, the situation changes: When editing a class which is *inherited from * (such as A), it is the editor's responsibility to check the effects of the edit on all inheriting classes.

Solution 4 - C#

To implement an interface, a class needs only to (a) declare that it is implementing that interface (such as your class B does), and (b) provide implementations for all the methods defined in the interface, either directly or indirectly via a base class (such as your class B does).

Solution 5 - C#

Section 13.4.4. of the C# specification states:

>Interface mapping for a class or struct C locates an implementation for each member of each interface specified in the base class list of C. The implementation of a particular interface member I.M, where I is the interface in which the member M is declared, is determined by examining each class or struct S, starting with C and repeating for each successive base class of C, until a match is located:

So it seems that this is well defined behavior, as the correct implementation of the FooMethod is not found in B, so a search is performed on its base class A where a method with matching signature is found. This is even explicitly pointed out in the same section of the spec:

>The members of a base class participate in interface mapping. In the example

interface Interface1
{
void F();
}
class Class1
{
	public void F() {}
	public void G() {}
}
class Class2: Class1, Interface1
{
	new public void G() {}
}

>the method F in Class1 is used in Class2's implementation of Interface1.

Solution 6 - C#

The feature is called inheritance. And if you don't like the design, just don't use it. A lot of people dislike inheritance, so you might, either. The definition of inheritance is, that all the members of the base class are also members of the derived one. So there isn't any compiler error. Therefore the Derived implements the contract IFoo provides. It's the base class member, which fulfills this requirement.

The beauty of it is, that you can implement an interface through a base functionality (virtual), which can be overriden if a Derived is expected to behave differently.

Solution 7 - C#

Interfaces are not inherited, interfaces are implemented. Thus when you derive a class from an interface, it means

> hey interface, you will find a method here which implements the method > signiture you have provided.

Since the base class has an implementation of the method, with the same method signiture defined in the interface, there will be no problems.

Even if you write a second interface with including the same method signiture it will still work.

interface IFoo2
{
    void FooMethod();
}

class B : A, IFoo, IFoo2
{
}

Solution 8 - C#

"But why should A know how to implement the FooMethod of the IFoo interface? A even doesn't know that IFoo exist."

A doesn't need to know about existence of interface IFoo. Its not A's responsibility to implement FooMethod correctly. Apparently A happened to implement the method which has same signature that of IFoo interface method FooMethod.

Its the responsibility of B to implement FooMethod since it is implementing IFoo interface. But since B is already having a method named FooMethod (inherited from A), it does not need to implement it explicitly. If an inherited method is not doing its job, B can new the method and write its own implementation.

Solution 9 - C#

B do implement IFOO. B inherits from A so it actually looks like this:

class B : IFoo  //Notice there is no A here. 
{
    public void FooMethod()
    {
        Console.WriteLine("implementation");
    }
}

And it is clear (from the above code) that B is implementing the IFoo and nothing is special.

Solution 10 - C#

While it is not particularly helpful to speculate as to why the creators of C# did what they did, and while I do not like this particular feature, I suspect part of the reason it works as it does is that there is no other good syntax to specify that an interface should be implemented by an already existing base-class method. Requiring that the derived class must define methods that do nothing but chain to the base-class implementation would seem ugly.

That having been said, I think it would have been cleaner for C# to resolve that general problem (interface methods that chain to other members are ugly) by providing a syntax to explicitly attach an interface member to a class member, than use auto-binding semantics to handle one particular situation but require chaining in a more common situation (implementation of interface by protected virtual method):

protected virtual IFoo_Method(int a, int b, int c) { ... }

IFoo.Method(int a, int b, int c) { IFoo_Method(a,b,c); }

While the JITter may be able to figure out that the IFoo_Method call should be in-lined, it really shouldn't have to. It would seem cleaner to declare that the protected method IFoo_Method should be regarded as the implementation of IFoo.Method.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOleg VazhnevView Question on Stackoverflow
Solution 1 - C#Marc GravellView Answer on Stackoverflow
Solution 2 - C#LukeHennerleyView Answer on Stackoverflow
Solution 3 - C#AakashMView Answer on Stackoverflow
Solution 4 - C#Matthew WatsonView Answer on Stackoverflow
Solution 5 - C#SWekoView Answer on Stackoverflow
Solution 6 - C#Michael SchnerringView Answer on Stackoverflow
Solution 7 - C#daryalView Answer on Stackoverflow
Solution 8 - C#Gaurav PhapaleView Answer on Stackoverflow
Solution 9 - C#Hossein Narimani RadView Answer on Stackoverflow
Solution 10 - C#supercatView Answer on Stackoverflow