5

In C#, as shown in the code snippet below, is it correct/proper to extend the interface IFoo when declaring the class A, knowing that the class BaseClass extends the interface IFoo? Is it necessary to specify the interface IFoo here, and is it best practice?

class A : BaseClass, IFoo
{
}

Might be a silly question, but what is the appropriate practice in this case?

Osama
  • 456
  • 4
  • 15
  • In C#, nothing extends an interface, nothing inherits an interface. Interfaces are implemented. – itsme86 Dec 22 '18 at 16:16
  • I wanted to differentiate between specifying that I want to implement an interface, and actually implementing it (its methods). – Osama Dec 22 '18 at 16:17
  • @itsme86 _"nothing inherits an interface"_ - incorrect. _"[...Interfaces can inherit from other interfaces...](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/)"_ –  Dec 22 '18 at 16:20

2 Answers2

5

If the BaseClass is Inherited from IFoo it is totally unnecessary to use IFoo in your Class A.

Check the image below (Resharper is used for this recommendation)

enter image description here


Special thanks to @InBetween

If interface reimplementation is the case, re-defining interface on child class has use case.

interface IFace
{
    void Method1();
}
class Class1 : IFace
{
    void IFace.Method1()
    {
        Console.WriteLine("I am calling you from Class1");
    }
}
class Class2 : Class1, IFace
{
    public void Method1()
    {
        Console.WriteLine("i am calling you from Class2");
    }
}

int main void ()
{
    IFace ins = new Class2();
    ins.Method1();
}

This method returns i am calling you from Class2

whereas,

interface IFace
{
    void Method1();
}
class Class1 : IFace
{
    void IFace.Method1()
    {
        Console.WriteLine("I am calling you from Class1");
    }
}
class Class2 : Class1
{
    public void Method1()
    {
        Console.WriteLine("i am calling you from Class2");
    }
}

int main void ()
{
    IFace ins = new Class2();
    ins.Method1();
}

returns I am calling you from Class1

Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72
  • Although 100% correct in the context of the OP’s question, generally speaking this answer is not always true. There is a little know language feature called *interface reimplementation* where redeclaring the interface is necessary. – InBetween Dec 22 '18 at 22:10
  • I just saw that you already add answer for your comment. I also edited my answer but if you want I can rollback my edit – Derviş Kayımbaşıoğlu Dec 22 '18 at 22:35
  • No, it’s ok, don’t worry – InBetween Dec 23 '18 at 08:29
2

Although the accepted answer is correct in your particular scenario, this is not always the case.

Redeclaring the interface in the class declaration can be useful and necessary: when you want to reimplement the interface.

Consider the following code, study it carefully:

interface IFoo {
    string Foo(); }

class A: IFoo {
    public string Foo() { return "A"; } }

class B: A, IFoo {
}

class C: A {  
    new string Foo() { return "C"; } }

class D: A, IFoo {
    string IFoo.Foo() { return "D"; } }

And now try to figure out what the following code will output:

IFoo a = new A();
IFoo b = new B();
IFoo c = new C();
IFoo d = new D();

Console.WriteLine(a.Foo());
Console.WriteLine(b.Foo());
Console.WriteLine(c.Foo());
Console.WriteLine(d.Foo());

Do you now see how redeclaring the interface (type D) can be useful?

Also, another good point to make is how the information in MSDN can be misleading seemingly implying that many interfaces are redeclared without any apparent reason in a lot of classes; many collection types for instance redeclare infinite amount of interfaces.

This is really not true, the problem is that the documentation is built upon the assembly's metadata and the tool can't really discern if the interface is declared directly in the type or not. Also, because its documentation, explicitly telling you the implemented interfaces, regardless of where they are actually declared, is a bonus even if its not 100% accurate with the source code.

InBetween
  • 32,319
  • 3
  • 50
  • 90