1

I came across a bit of code and am not quite sure why it works or why you'd want to do it this way. I would love it if someone could tear it down for me. I do understand well OOP concepts, I simply have not seen this technique before. Thanks

Here is the example:

public interface IInterface
{
    IEnumerable<object> DoSomething();
}

public abstract class MyBase : IInterface
{
    protected MyBase()
    {
    }

    IEnumerable<object> IInterface.DoSomething()
    {
        return DoSomething();
    }

    protected virtual IEnumerable<object> DoSomething()
    {
        return new List<object>();
    }
}

public class MyClass : MyBase
{
    internal MyClass() : base() {}

    protected override IEnumerable<object> DoSomething()
    {
          return new List<object>();
    }
}
Kirby
  • 1,739
  • 1
  • 17
  • 21
  • 1
    It's not clear which aspect of the example you're confused by. – Jon Skeet Mar 11 '13 at 16:04
  • I'm guessing it is the explicit interface implementation with the protected implicit implementation (if that's what it is - I'd have said that implicit interface implementations are public). – Colin Mackay Mar 11 '13 at 16:07
  • My apologies. The part that confuses me is what looks to me as a private implementation of the IInterface.DoSomething returning the virtual DoSomething. I also noticed the IInterface. is required for it to compile. – Kirby Mar 11 '13 at 16:10
  • This doesn't make sense. Looks like someone tried to hide `DoSomething` from the base class. – Ilia G Mar 11 '13 at 16:11

5 Answers5

1

If you're talking about this line of code:

IEnumerable<object> IInterface.DoSomething()

That's called explicit interface implementation.

That forces consumers to access this method only via the interface, and not to your class directly.

The above method is not private, it's just not explicitly set as public in code. In fact, with explicit interface implementation, you can't even use access modifiers.

One of the reasons for taking this approach is to force better coding practices. If you're the developer of this class, and you know it should only be accessed via an interface, this is the way to force that to happen.

Bob Horn
  • 33,387
  • 34
  • 113
  • 219
  • I know about explicit interface imp, and I know it comes in handy when you use more than one interface that happen to have the same named methods. I'm still not sure why the programmer did the above and what benefit it gives. – Kirby Mar 11 '13 at 16:19
  • 1
    It's not only about using one interface when there are two defined; it's about forcing a class to be consumed via an interface instead of directly using the class itself (even when just one interface is involved). My answer shows a reason why to do this. – Bob Horn Mar 11 '13 at 16:21
  • In C#, you cannot modify an explicit interface implementation - it's always private. In VB.NET, I believe you can make an explicit implementation whatever access you want. Personally, I like the C# way better. – Joe Enos Mar 11 '13 at 16:26
  • 1
    @JoeEnos It's not `private`. Nor is it `public`, or `internal`, or...anything. You can't specify an access modifier because *none of the make sense. You access it through the interface, thus the accessibility is the accessibility of the interface itself, nothing more. You couldn't possibly specify `private`, because if you did then you wouldn't be meeting the interface's contract. If it was `public` you may be exposing the method to a scope larger than the interface. In the end, allowing the access modifier is at best, redundant, and at worst, violating the interface contract. – Servy Mar 11 '13 at 16:33
  • Check out [Skeet's answer and comments](http://stackoverflow.com/a/1392281/111266) - all depends on your perspective. But in VB, it can be explicitly private or public (or any other I think): `Public Sub Go() Implements ISomething.Go` is valid and will allow you to access `Go` through the interface or not - `Private Sub Foo() Implements ISomething.Foo` is also valid, and behaves the same way C# does, only allowing access through the interface. – Joe Enos Mar 11 '13 at 16:43
  • Re my previous comment: Private explicit implementation in VB behaves *almost* the same way C# does - in VB, you can call this method from other methods inside the class, where in C# you have to cast `this` to the interface before calling the method. – Joe Enos Mar 11 '13 at 16:58
  • Thanks everyone for such great answers. @BobHorn, could you elaborate a little on why this would be a "better coding practice" and what are the possible reasons/scenarios why you'd want to force the interface use. I'm not so sure that this technique is not a little overkill in our code. – Kirby Mar 11 '13 at 17:05
  • @NinjaCoding I thought I answered that with the last sentence in my answer. When designing a system, you sometimes know that it doesn't make sense to access the class directly. Perhaps the scenario is a rules engine, where you process each class polymorphically. If you know that when you design it, you can prevent calling the class directly by using this technique. – Bob Horn Mar 11 '13 at 17:47
1

In C#, explicitly implementing an interface by using a sealed method which does nothing but call a protected virtual method allows derived-classes great flexibility with regard to what they want to do with the interface; the method should be given a name other than the name of the interface method (in the above example, it could perhaps be DoSomething_Prot). Explicit interface implementation makes it impossible for a derived class re-implementation to chain to the base-class implementation, but if the only thing the base-class implementation is doing is chaining to a protected virtual or abstract method, there's no need for a derived class to re-implement the interface. Further, even if the derived class were to re-implement the interface either deliberately or as a result of covariance it would still be able to invoke the "guts" of the base-class implementation using the protected method from the base class.

Putting all the code for the interface implementation in a public virtual method which implicitly implements the interface is better than putting code in an explicit implementation, since derived-class code can generally chain to the private member. Such an approach, however, requires that all derived classes publicly implement the method with the same signature. While it may seem like what one would naturally expect anyway, it isn't always. For example, in the above example a derived class may wish to have its DoSomething method return a type other than IEnumerable<object> (e.g. it might return an IList<Kangaroo>). The method which implements the interfae would still have to return precise type IList<Kangaroo>, but code that knew it was dealing with the derived type could use the return type as an IList<Kangaroo> without a typecast. If the actual code for the method were in a method called DoSomething_Prot(), the derived class could both override DoSomething_Prot and declare a new public IList<Kangaroo> DoSomething(). If the base-class method were called DoSomething(), there would be no way for the derived class to both override it and define a new method with a different return type.

supercat
  • 77,689
  • 9
  • 166
  • 211
0

Off the top of my head I'm having trouble of thinking of a practical use for this, but one thing that this accomplishes is that objects of type MyBase or its subclasses do not have a public or internally visible DoSomething() method:

MyClass a = new MyClass();
a.DoSomething();  // Compile error

but the DoSomething() method is visible when the object is used as an IInterface:

void AMethod(IInterface i)
{
    i.DoSomething(); // compiles just fine
}

void AnotherMethod(MyBase a)
{
    AMethod(a); // as does this
}

Making the non-explicit version protected virtual allows subclasses to override the behavior of the DoSomething() method.

This is a way of implementing a method that cannot be called directly when working with MyBases as MyBases, but can be used when they are being treated as IInterfaces. There's nothing to prevent someone from doing this: ((IInterface)a).DoSomething(); but it seems the hiding is done for semantic reasons.

JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • For some more info on use, there is a factory class in the same assembly that creates and returns the MyClass. The class that uses that MyClass is also in the same assembly and it calls the method w/o problem. Example var myClass = SomeFactory.GetMyClass(); myClass.DoSomething() – Kirby Mar 11 '13 at 16:17
  • That's probably because `GetMyClass()` returns an interface, not a concrete myBase or myClass. – Bob Horn Mar 11 '13 at 16:20
  • Yes the factory method returns an interface. – Kirby Mar 11 '13 at 16:23
  • That would explain why the method is being called w/o problem. – JLRishe Mar 11 '13 at 16:26
  • I think my answer offers a purpose for this construct, though the protected `DoSomething()` method should have a name or parameter signature which differs from that of the interface method. – supercat Mar 11 '13 at 16:46
0

My take on this is that it is an implementation of the template pattern as described here. Typically you see the template pattern used along with the strategy pattern. In your particular example, users of the IInterface could call the DoSomething method without regard for how the concrete subclass implemented the method.

This kind of OO programming allows you to take advantage of quite a few other patterns such as the AbstractFactory for creating your concrete subclasses of MyBase which implement IInterface.

nattyddubbs
  • 2,085
  • 15
  • 24
0

The important thing to note is that the two DoSomething methods have nothing to do with each other - they just happen to have the same name.

Basically, you've just got a normal interface that exposes a DoSomething method, so the caller who has a IInterface object can call it. It will then in turn pass the call on to the appropriate implementation of the protected DoSomething method, which can either be from the base class or the derived one.

Explicit implementation like this forces you to code by contract instead of implementation - doesn't really provide any actual protection, just makes it more difficult to accidentally use the wrong type when you declare your variable. They just as easily could have done:

public abstract class MyBase : IInterface {
    public virtual IEnumerable<object> DoSomething() {
       // blah
    }
}

public class MyClass : MyBase {
    public override IEnumerable<object> DoSomething() {
        // blah
    }
}

but that would let you call DoSomething on a variable declared as MyClass or MyBase, which you may not want them to do.

Joe Enos
  • 39,478
  • 11
  • 80
  • 136
  • This explanation makes things a lot clearer to me. Would you also agree with nattyddubbs that this looks like a templates pattern? I will need to do some reading up on that pattern. – Kirby Mar 11 '13 at 16:32
  • That seems about right - never called it a template pattern before, but that's pretty much straightforward inheritance-based OOP - base class and overridden methods in your child classes to make them behave how you want it to. – Joe Enos Mar 11 '13 at 16:47
  • wanted to give you props by voting you up but my rep is not high enough yet. Thanks again for pointing out the naming nugget! – Kirby Mar 11 '13 at 18:31