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

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?


Solution 1:

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:

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:

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:

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:

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.