Explicit/implicit interface implementation in C#
In the C++ world we are only used to one way of implementing an interface in a class, but in C# you have two options: either an implicit implementation, like the one in C++, or an explicit interface implementation.
Consider the following code:
public interface ITest
{
void DoStuff();
}
public class Test : ITest
{
/// Explicitly implement an interface
void ITest.DoStuff()
{
System.Diagnostics.Debug.WriteLine( "Test is doing stuff" );
}
}
In the code above we define an interface with a method called DoMethod which is implemented by the class Test. The cool thing is that we now have associated a method implementation explicitly with a method on an interface, first and foremost this means that we do not have to mark the visibility of the method (public, protected, etc.). Additionally it also means that if the method declaration in the interface is modified in some way, e.g. if a parameter is added or removed, we will get a compile error saying the our implementation of DoStuff does not match the one in the interface, with implicit interface implementation we are only told that Test does not implement the new DoStuff method.
Where it gets really cool is when you consider what happens if a method is removed from the interface, this shows up as a compilation error when we use explicit interface implementations, where as with implicit interface implementations the method can linger around in a class for a long time, before it is noticed as implementing a method of a previous interface revision.
public interface ITest
{
}
public class Test : ITest
{
/// Compilation error, no method DoStuff on ITest interface
void ITest.DoStuff()
{
System.Diagnostics.Debug.WriteLine( "Test is doing stuff" );
}
}
So far this is a really cool thing, I like things that are checked at compile-time, and I especially like any technology that can help implement interfaces and keep interface implementations in sync with interface definitions.
But, and this is a big but, when you start using a class which implements an interface explicitly you are left with one big thorn in your eye, you would think that writing something like the following should be possible:
class Program
{
static void Main( string[] args )
{
Test test = new Test();
test.DoStuff();
}
}
But what are we faced with? Compile errors! The compiler claims that Test does not contain a definition of a DoStuff method. This is really contrary to the common belief that when you implement an interface in a class, you can call those methods on instances of that particular class directly. In this case you first need to cast test to ITest to be able to call the method.
Even more horribly, this means that how you implement an interface in a class, implicitly or explicitly, changes how that class can be used - this is the one that really baffles me - it seems like complete abandonment of good clean object oriented design.
Now, I think I understand why this was done, the whole reason for allowing for explicit interface implementation is probably to make it possible to distinguish implementations of similarly named methods in separate interfaces, e.g. ITest.DoMethod() and ISecondTest.DoMethod(). But I find it strange that mr. Hejlsberg have overlooked the advantages of explicit interface implementations.
Comments:
Well if the user can still do an explicit cast it is still only cosmetic safety - in a statically compiled language i expect this kind of safety to be enforced by the compiler.
The first use you mention does not apply in my opinion, you can just make your method return the interface rather than the class.
Unless, of course, i have misundertood something completely ;-)
This can be used , for example when you implement an interface in a class and you want class user to use interface only, and to not reference implementation class (which other functions could change).
Another use: When you have an interface that is "internal" to your code, and that is implemented to do certain things the user don't have to know. For example if you manage your objects yourself with your own instance manager class, your object class may implement IDisposable, but you don't want the user to see IDisposable interface in final objects, because you don't want him to call "Dispose()". (however, he can still do it, but he needs to do an explicit cast). This is some kind of "private interface implementation" (in C++ you can implement interface as protected, in C# you can't, you could use this way).
Even if syntactically it does the job, it was not designed to implement different interfaces with same members.