In this post I'll talk about VB's explicit interface implementation and how to best exploit the power this brings. I guess that it's a well known fact that interface implementation in VB is explicit but what does that mean really? It simply means that to implement an interface in a class the developer has to explicitly declare what members of the class implements the members of the interface. C# also has the ability to explicitly implement interfaces but it supports implicit interface implementation too which lets you implement an interface by declaring members with the same names and signatures as those of the interface. To implement the IDisposable interface implicitly we'd write the following:
public class Foo : IDisposable { public void Dispose() { // Implementation here... } }
The developer never tells the compiler that the method named "Dispose" implements the method "Dispose" of the IDisposable interface, the compiler figures this out by comparing the name and the signature of the method. To explicitly implement an interface in C# we'd write the following instead:
public class Foo : IDisposable { void IDisposable.Dispose() { // Implementation here... } }
In this implementation we explicitly say that the "Dispose" method implements the "Dispose" method of the interface IDisposable, note that there is no scope declared for this method, this is because it's only accessible through the interface. If you held an instance of the class "Foo" you would not be able to invoke the Dispose method without casting the instance to IDisposable.
Foo foo = new Foo(); foo.Dispose(); // will not compile (foo as IDisposable).Dispose(); // will compile
As seen here this means that a method that implements an interface method must have the same name as the interface method and be public OR have no name at all and be private (explicit implementation). In VB on the other hand where implementation is always explicit we have a lot more freedom regarding naming and scope. For example a method implementing an interface method can have any scope (Private, Protected, Friend or Public) and also any name. Oh, well, any valid name that is.
Public Class Foo Implements IDisposable Public Sub ThisMethodIsNotNamedDispose() Implements IDisposable.Dispose ' Implementation here... End Sub End Class
Now we have a public method called something completely different than "Dispose" but still implementing the "Dispose" method, if you were to cast an instance of the Foo class to the IDisposable interface and call the "Dispose" method on it the method "ThisMethodIsNotNamedDispose" would be invoked. As I said earlier an implementing method can have any scope, the method "ThisMethodIsNotNamedDispose" could just as well have been made private for example and we would end up with a situation very similar to the C# way of explicitly implementing interfaces. One very big difference though is that from within the class Foo you'd be able to call the method "ThisMethodIsNotNamedDispose" even though it's private, in C# however you can never call an explicit member implementation without casting to the interface, not even from within the implementing class itself.
Another cool thing about VB's explicit interface implementation is that a single method or property can implement methods or properties from multiple interfaces at the same time.
Public Class Foo Implements ICollection, ICountable '... Public ReadOnly Property Count() As Integer Implements ICollection.Count, ICountable.Count Get Return theCount End Get End Property '... End Class Public Interface ICountable ReadOnly Property Count() As Integer End Interface
Interface implementation is one of the very few areas where I think VB outshines C# (XML-literals being the other area).
I think that hiding the methods of the interface in the public interface of the class (by explicitly implement the interface in C# and setting a non public scope in VB) is something that should be sparsely used. I use it only when a method makes no sense when the concrete type is known. For example if you create a LinkedList that implements the ICollection(T) interface there is really no need to ever call the "IsReadOnly" property when you know that you're holding a LinkedList that is never read only, this interface property should be hidden from the public interface of the class.
I've used the IDisposable interface as an example here but I would strongly advice against ever hiding the "Dispose" method of this interface in production code.