2

I'm very aware of the fact that such a question has probably been posted already. Yet with the involvement of IoC in this case and a lot of code I've seen a colleague in a company I'm new in made this question arise.

Scenario:

In the codebase of one product this colleague build every interface is implemented explicitly. The whole application is constructed through structure map, yet in some places the concrete types are used and cast like this

((IInterface)concreteClass).SomeMethod()

Background:

That colleague explained to me, after asking what it is about explicitly implementing all interfaces, that they introduced StructureMap recently and many people would still just use the concrete types. So in essence it's a means to "educate" people in the company.

My cents on the matter:

First of all, the switch to StructureMap has been done several years ago and while this, sort of, forces to use interfaces more, in my opinion this is not the right way. The way I see it, people who know about the concrete type can see the implementation and easily to what I showed above... just cast it. Clear communication or coding conventions would make this much better. If IoC is used and no concrete class, then explicitly implmenting an interface is completely useless.

I've also heard that this can really mess up inheritance, but don't know of an example. I've also seen Jon Skeet sort of discouraging from using it the way mentioned above, but rather the way it was intended to use, like with IEnumerable<> and other name clashes.

Can anyone shed some light on this matter for me. Pros and cons (although I'm highly biased to not doing it, hence my post here) and especially reasons why one or the other.

Thanks!

Edit: I'm very well aware that this is not a matter of right or wrong, nor is there a real answer. This is more of a question to learn to know deficits of each approach. Why would I use in one scenario one over the other approach?

Alex Endris
  • 444
  • 4
  • 16

2 Answers2

0

A good starting point could be this article: Why I use explicit interface implementation as a default implementation technique

Initially I wasn't to inclined on implementing interfaces explicitly but I have to admit the writer makes some very good points.

UPDATE: In comments below, the OP is stating that explicit implementation screws up inheritance as you can not override the interface implementation in a derived type. I'm not sure if I'm undestanding correctly the issue:

public interface IFooable
{
     void Foo();
     void FooAgain();
}

public class Blah: IFooable
{
     void IFooable.Foo()
     {
         Console.WriteLine("Hi from 'Blah'!");
     }

     void IFooable.FooAgain() {}
}

public class Bar: Blah, IFooable
{
     void IFooable.Foo()
     {
         Console.WriteLine("Hi from 'Bar'!");
     }
}

public static void Main()
{
   var fooList = new List<IFooable>();
   fooList.Add(new Blah());
   fooList.Add(new Bar());

   foreach (var fooable in fooList) //Outputs "Hi from 'Blah'!" / "Hi from 'Bar'!"
       fooable.Foo();

   Console.ReadLine();
}
InBetween
  • 32,319
  • 3
  • 50
  • 90
  • 1
    I've read that one already. The problem with this is that you can argument exactly the same against it. I personally would only use explicit interface implementation when it is really necessary as it can screw up things as well and you don't really have any benefit in using it over normal implementation. But I'd really like to hear more of both sides. Why discourage it or why encourage it. What, in your opinion, makes it worth using and what do you gain from it? Thank you! – Alex Endris Sep 08 '14 at 16:14
  • 1
    @Qudeid Personally I use explicit implementations when the interface tends to be used by not so transparent mechanisms of the framework. Typical example would be `IConvertible`. I haven't seen that much code directly calling a method of this interface, it's normally leveraged through `System.Convert` Still I'm not really sure there is a right or wrong way to do it, it's more of a coding style I guess. – InBetween Sep 08 '14 at 16:29
  • No there isn't a right way. It is supposed to me more of a discussion as to what are problems you can run into when you go one way or the other. The problem I see with the post above is that someone states the reason of HIS usage, but he omits a lot of things as well. It feels a lot like he's preaching, considering the comments down below. Perhaps I should edit into my question that this is supposed to be more of a discussion than question. – Alex Endris Sep 08 '14 at 16:38
  • @Qudeid - Explain "screw up things". You mentioned that several times, but sort of hand waved over it... What do you mean? – Erik Funkenbusch Sep 08 '14 at 18:23
  • @Erik What I have in mind with "screw up things" is inheritance. Once you've explicitly implemented an interface, you can't inherit from that one class and override the implementation. Obviously, there is a workaround, as stated in the codeproject article, IIRC. write a virtual method, that has the implementation of an interface method and only call that in the interface implementation. But then I wonder, why all the hassle? Working around something you, probably, didn't even need. (Unless, ofc, there are name clashes, like with IEnumerable/IEnumerable<>. – Alex Endris Sep 08 '14 at 20:47
  • @Qudeid I'm not sure I follow you. Of course you can override the implementation, you just explicitly implement the interface again in the derived type. I've updated my answer with a code example. Maybe I'm misunderstanding you. – InBetween Sep 08 '14 at 21:20
  • @Qudeid In C# interface implementations, explicit or not, are always virtual. In CIL the method of an interface is marked as `virtual` and `abstract`. I'm not sure what your issue with inheritance and explicit implementation is. – InBetween Sep 08 '14 at 21:32
  • @Erik You have no argument, but you try to argument against me. Explain please. – Alex Endris Sep 08 '14 at 21:47
  • @InBetween No. An Explicit implementation of an interface is not virtual. What you do in your code is make Bar inherit twice from IFooable. Why would you ever need to do that as Blah already is an IFooable. The code you provided already states that it is not virtual. To me, this is a code smell and not at all necessary. Only because you CAN do something, doesn't mean it is good or the right way. (At least not generally) – Alex Endris Sep 08 '14 at 21:50
  • @InBetween Besides, what does this code: void DoSmth(Blah blah) { ((IFooable)blah).Foo(); }? – Alex Endris Sep 08 '14 at 22:00
  • @Qudeid You are wrong, explicit implementation is virtual *but* not overridable. In order to override it you need this hack. CIL marks it as `virtual final`. – InBetween Sep 08 '14 at 22:00
  • @InBetween sorry, but this is nitpicking. "final" states it. It ends there. Putting the interface in a derived class again is, as you state it yourself, a "hack". Certainly not nice code. – Alex Endris Sep 08 '14 at 22:03
  • @Qudeid Of course its nice code. The .NET framework is full of similar cases. Just take a look at the definition of `List`. It implements, among others, `IList`, `ICollection` and `IEnumerable`. You can't get more redundant: `IList` goes ahead and implements `IColletion` and `IEnumerable` and `ICollection` implements `IEnumerable`. Thats 3 redundant `IEnumerable` and 2 `ICollection`. Your point is mute. – InBetween Sep 08 '14 at 22:13
  • @Qudeid: StackOverflow is a Q&A site, not a discussion forum. Most of us are here to help answer people's questions. Your question wasn't very clear in the first place, and now you're splitting hairs about the difference between being able to define a new explicit implementation versus being able to override a parent class's explicit implementation. You're coming across as if you asked the question to provoke an argument. You may want to consider whether this is the right place to be having this sort of discussion. – StriplingWarrior Sep 08 '14 at 23:34
  • @StriplingWarrior Considering the amount of developers that possibly read this, yes it is the right place. – Alex Endris Sep 09 '14 at 05:45
  • @InBetween There is a difference between a defined framework and codes used for your special needs. It being nice code is subjective, but it's not subjective that it has a communicational problem. When I see the code I asked you what it does, then I look up "Blah". I see it's explicitly implemented and consider it ends there. Why would you write complicated code, just to get something working that works out of the box with virtual once you implicitly implemented the interface? Consider that. – Alex Endris Sep 09 '14 at 05:47
  • 1
    @Qudeid I completely agree. If I have a *choice* I'd never do it this way. But I've seen a case where it was necessary to "override" the behavior of an explicitly implemented interface and this is how it was done because there was no other choice. Its possible. Obviously if you are building the code from scratch and overriding the implementation is a plausible scenario, I wouldn't do it like this. Still, explicit interface implementation make a good case even in this scenario. Protected virtual methods lets you override implementation. Advantages: public API decluttering, refactoring, etc. – InBetween Sep 09 '14 at 08:26
  • @InBetween Don't get me wrong. I am not saying that one should never use explicit interface implementation. My point is that one should think what benefits you get from it. If I consider my stated scenario above, what is the benefit for defaulting to explicit interfaces? Sure, there is essentially no difference if there is no inheritance (run-time) if there is not much inheritance and if only the interface is used. But like StriplingWarrior said, why preemptively using this to discourage concrete class usage? For me, this smells. – Alex Endris Sep 09 '14 at 08:47
0

There are two main potential advantages to explicit interface implementations:

  1. A single class can implement two interfaces that have conflicting method signatures, and subtly different implementations for each. It is rare for this to happen, and it's typically not a problem to do on-demand rather than by-default.
  2. You can "hide" certain methods that you don't expect people to use except in specific contexts. The Interface Segregation Principle encourages us to not expose methods to consumers that they are unlikely to need.

One good example of #2 being used is the way that Entity Framework contexts avoid exposing their underlying ObjectContext directly (because most people shouldn't be using it in their code), but still make this property available if you cast the context to an IObjectContextAdapter.

In the case of your company, it sounds like they're trying to leverage #2, but for the wrong reasons. They want to hide method implementations, not because the method isn't expected to be used, but because they do expect it to be used--and when it is they're hoping it'll encourage developers to decouple their code from the concrete types. Your code sample indicates that it is missing the mark--developers are still instantiating concrete types and then casting them in order to get access to the interface methods.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • to 1. Yes, that is the reason you use it for implementing, for instance, IEnumerable and IEnumerable<>. to 2. I wonder if you understoof the ISP correctly. ISP is strictly about interfaces. That means, if you can separate one interface into two interfaces, because the consumer doesn't use much of the 2nd interface, thus doesn't need to know about this stuff. Explicit interface implementation doesn't enforce ISP. Also, no, ISP isn't enforced there this way. What needs to separated is separated, but not though explicit interface implementation. This is a different matter there. – Alex Endris Sep 08 '14 at 20:41
  • 1
    @Qudeid: I think the ISP relates to interfaces as a *concept* rather than as a language construct. In that sense, every concrete type exposes "interfaces" with varying visibility based on privacy modifiers, and every `interface` it implements also exposes another "interface" with visibility based on *its* privacy modifier. An `interface` may define only a subset of the methods implemented by the concrete class, and (using explicit interface implementation), the class may expose only a subset of its total available functionality as public methods. Do you see where I'm coming from? – StriplingWarrior Sep 08 '14 at 23:15
  • Naturally a class has the interface of its public members. The question here is always what do I want to achieve. For example the code suggestion from InBetween. While this is 100% valid code and works, doesn't mean it's good code.Code tells a story and since more people than just me need to read (and we read more code than we write) it is very important to tell your story nice and shiny and not confusing and ambiguous. Btw. at the time of writing my last comment to this answer I havent considered what you just stated about interfaces being a language constrct. You are right. – Alex Endris Sep 09 '14 at 05:54