13

Take this example:

public interface IFoo
{
    IFoo Bar();
}

public class Foo : IFoo
{
    public Foo Bar()
    {
        //...
    }

    IFoo IFoo.Bar() { return Bar(); } //Why is this necessary?
}

Why is the implicit implementation of IFoo Bar() necessary even though Foo converts to IFoo without a cast?

Matt
  • 21,026
  • 18
  • 63
  • 115
  • Why are you doing this at all? You are effectively tying users of `Foo` to the concrete implementation, making mocking for unit tests difficult, and generally increasing coupling in your application... – Steve Czetty Dec 19 '12 at 19:45
  • The two approaches are pretty much mutally exclusive. Both work but have different purposes. You wouldn't use both approaches for the same interface in the same concrete class (at least not that I can think of) – dkackman Dec 19 '12 at 19:47
  • @SteveCzetty Hence the OP's question; where explicitly implementing the interface is necessary. – Aaron McIver Dec 19 '12 at 19:51
  • @AaronMcIver My point is that any class that references the concrete version of `Foo` (instead of `IFoo`) is going to be coupled to that particular implementation. – Steve Czetty Dec 19 '12 at 19:54
  • possible duplicate of [implicit vs explicit interface implementation](http://stackoverflow.com/questions/598714/implicit-vs-explicit-interface-implementation) – David Basarab Dec 19 '12 at 20:33

5 Answers5

5

Microsoft has a detailed write up on the subject but it boils down to the implementation of multiple interfaces/classes which have the same method in them. Implicit no longer works in that context.

class Test 
{
    static void Main()
    {
        SampleClass sc = new SampleClass();
        IControl ctrl = (IControl)sc;
        ISurface srfc = (ISurface)sc;

        // The following lines all call the same method.
        sc.Paint();
        ctrl.Paint();
        srfc.Paint();
    }
}


interface IControl
{
    void Paint();
}
interface ISurface
{
    void Paint();
}
class SampleClass : IControl, ISurface
{
    // Both ISurface.Paint and IControl.Paint call this method.  
    public void Paint()
    {
        Console.WriteLine("Paint method in SampleClass");
    }
}

// Output: 
// Paint method in SampleClass 
// Paint method in SampleClass 
// Paint method in SampleClass

If we were to take the explicit approach, we end up with this.

public class SampleClass : IControl, ISurface
{
    void IControl.Paint()
    {
        System.Console.WriteLine("IControl.Paint");
    }
    void ISurface.Paint()
    {
        System.Console.WriteLine("ISurface.Paint");
    }
}

It all boils down to providing uniqueness when the implemented types clash. In your example, Foo is IFoo.

Aaron McIver
  • 24,527
  • 5
  • 59
  • 88
5

It's needed in this case because C# does not support return type co-variance for interfaces, so your function

public Foo Bar()
{
    //...
}

does not satisfy the IFoo interface since the return type of the Bar method is different.

Since you want to also implement the interface, your only choice is to do so explicitly since you already have a Bar() method defined on the class.

Lee
  • 142,018
  • 20
  • 234
  • 287
  • Yes, but **why** doesn't C# allow this? – Ilya Kogan Dec 19 '12 at 19:52
  • 2
    @IlyaKogan - I don't know why C# doesn't support return-type covariance - you'd have to ask the designers. C# generally prefers that things are made explicit, so it's probably to prevent interfaces from being accidentally implemented implicitly. – Lee Dec 19 '12 at 19:56
  • 1
    @IlyaKogan This goes back to every question on _why_ with regards to implementation; because they chose to. – Aaron McIver Dec 19 '12 at 19:59
  • @AaronMcIver Usually an implementation choice can be explained logically. – Ilya Kogan Dec 19 '12 at 20:18
  • @IlyaKogan A lot of times, it's just that they thought there were more important things to spend time on. – Erix Dec 19 '12 at 20:29
4

You can solve it like this (a bit ugly, but takes care of the strong typing):

public interface IFoo<T> where T : IFoo<T>
{
    T Bar();
}

public class Foo : IFoo<Foo>
{
    public Foo Bar()
    {
        //...
    }
}
Ilya Kogan
  • 21,995
  • 15
  • 85
  • 141
3

Because you may not always want the method implementing the interface to behave the same way as another version of the method with the same signature.

You may also want a class to implement a method for an interface but for that method not be be accessible from an instance of the class itself.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
0

I'd recommend that you kept the implicit implementation as protected instead of public.

public class Foo : IFoo
{
    **protected virtual** Foo Bar()
    {
        //...
    }

    IFoo IFoo.Bar() { return Bar(); } 
}

there is a pretty extensive answer for why/when to use explicit implementation in this thread:

implicit vs explicit interface implementation

A good reason for using the explicit implementation is that you can easily use dependency injection to have a more loose coupling when you use your Foo class.

Community
  • 1
  • 1
Moriya
  • 7,750
  • 3
  • 35
  • 53