6

Is there any reason why an interface reference would be included before a method name on an implementing class? For example, let's say you have a ReportService : IReportService and a GetReport(int reportId) method. I was reviewing some code and another developer implemented the method like this in ReportService:

Report IReportService.GetReport(int reportId)
{
  //implementation
}

I've never seen a service implementation like this before. Does it serve any purpose?

user7242966
  • 347
  • 1
  • 10
  • Pretty sure it's so you can differentiate in case the implementing class has a method with the same signature. – Tobias Dec 30 '16 at 18:28
  • Explicit interface implementations don't allow you to use visibility modifiers. I'm pretty sure you simply typed it wrong in your question here so went ahead and edited it. If you think I'm wrong, if you think the `public` was really there, feel free to revert, but then what you had couldn't compile. –  Dec 30 '16 at 18:32

1 Answers1

12

This is called "explicit interface implementation". The reason for this may for example be a naming conflict.

Consider the interfaces IEnumerable and IEnumerable<T>. One declares a non-generic method

IEnumerator GetEnumerator();

and the other a generic one:

IEnumerator<T> GetEnumerator();

In C# it's not allowed to have two methods with the same name that only differ in there return type. So if you implement both interfaces, you need to declare one method explicit:

public class MyEnumerable<T> : IEnumerable, IEnumerable<T>
{
    public IEnumerator<T> GetEnumerator()
    { 
        ... // return an enumerator 
    }

    // Note: no access modifiers allowed for explicit declaration
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator(); // call the generic method
    }
}

Explicitly implemented interface methods cannot be called on instance variables:

MyEnumerable<int> test = new MyEnumerable<int>();
var enumerator = test.GetEnumerator(); // will always call the generic method.

If you want to call the non-generic method, you'd need to cast test to IEnumerable:

((IEnumerable)test).GetEnumerator(); // calls the non-generic method

That also seems to be the reason why there are no access modifiers (like public or private) are allowed on explicit implementations: it's not visible on the type anyway.

René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • also you can implement from interface explicitly to implement something non publicly (which can be another reason). – M.kazem Akhgary Dec 30 '16 at 18:36
  • @M.kazemAkhgary Indeed. What's worth adding to that if a public class implements an internal interface, and the internal interface declares a method with an internal return type, the public class *cannot* implement it as a public method, it *must* resort to explicit interface implementation. –  Dec 30 '16 at 18:59