7

I use interfaces for decoupling my code. I am curious, is the usage of explicit interface implementation meant for hiding functionality?

Example:

public class MyClass : IInterface
{
     void IInterface.NoneWillCall(int ragh) { }
}

What is the benefit and specific use case of making this available only explicitly via the interface?

Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246
PRASHANT P
  • 1,527
  • 1
  • 16
  • 28
  • What if `IHourCalculator` and `IMinuteCalculator` both have a `GetTime()` method? Makes it nice to be able to `((IHourCalculator)foo).GetTime()` could be called directly. ;-) – Brad Christie May 25 '11 at 19:39
  • possible duplicate of [implicit vs explicit interface implementation](http://stackoverflow.com/questions/598714/implicit-vs-explicit-interface-implementation) – unholysampler May 25 '11 at 19:39

4 Answers4

11

There are two main uses for it in my experience:

  • It allows you to overload methods by return value. For example, IEnumerable<T> and IEnumerable both declare GetEnumerator() methods, but with different return types - so to implement both, you have to implement at least one of them explicitly. Of course in this question both methods are provided by interfaces, but sometimes you just want to give a "normal" method with a different type (usually a more specific one) to the one from the interface method.
  • It allows you to implement part of an interface in a "discouraging" way - for example, ReadOnlyCollection<T> implements IList<T>, but "discourages" the mutating calls using explicit interface implementation. This will discourage callers who know about an object by its concrete type from calling inappropriate methods. This smells somewhat of interfaces being too broad, or inappropriately implemented - why would you implement an interface if you couldn't fulfil all its contracts? - but in a pragmatic sense, it can be useful.
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • i have read again. how have i not notice this in IENumerable !! i am foolish – PRASHANT P May 25 '11 at 19:57
  • 3
    "Discouragement" also allows you to effectively "rename" the interface methods. For example, you might have class C : IDisposable { void IDisposable.Dispose() { this.Close(); } public void Close() { ... } } -- that way you get a public Close method, you don't see the potentially confusing Dispose method, and yet you can still use the object in a context where IDisposable is expected, like a "using" statement. – Eric Lippert May 25 '11 at 20:14
  • @Eric: Of course if C# allowed you to implement interface methods using different *actual* method names, we wouldn't need to use two different methods for this :) (It's entirely possible that I don't understand VB interface implementations of course - and I wouldn't be surprised if it compiled down to the same code as the C# explicit interface implementation.) – Jon Skeet May 25 '11 at 20:16
  • Good point. And I'm pretty sure VB does the same thing as C#: it makes an entry in the MethodImpl table in metadata telling the loader that this class method over there is the implementation of that interface method, and so on. – Eric Lippert May 25 '11 at 20:20
4

One example is ICloneable. By implementing it explicitly, you can have still have a strongly typed version:

public class MyClass : ICloneable {
    object ICloneable.Clone() {
       return this.Clone();
    }

    public MyClass Clone() {
       return new MyClass() { ... };
    }
}
CodeNaked
  • 40,753
  • 6
  • 122
  • 148
  • 1
    One of my pet peeves is "clone" methods which return Object. On the occasions when I implement ICloneable, I also implement ICloneable(Of Out T). – supercat May 26 '11 at 18:02
3

It is not meant for hiding methods but to make it possible to implement two methods with the same signature/name from different interface in to different ways.

If both IA and IB have the operation F you can only implement a different method for each F by explicitly implementing the interfaces.

Emond
  • 50,210
  • 11
  • 84
  • 115
2

It can be used for hiding. For example, some classess that implement IDisposable do so explicitly because they also have a Close() method which does the same thing.

You can also use the explicit interface definitions for when you are implementing two interfaces on one class and there is a signature clash and the functionality differs depending on the interface. However, if that happens it is usually a sign that your class is doing too much and you should look at splitting the functionality out a bit.

Colin Mackay
  • 18,736
  • 7
  • 61
  • 88