Explicit interface implementation in .NET Part 1
August 7, 2015 Leave a comment
The generic and well-known Dictionary object and its generic and thread-safe counterpart, i.e. the ConcurrentDictionary object both implement the generic IDictionary interface. The IDictionary interface has an Add method where you can insert a new key-value pair into a dictionary:
Dictionary<string, string> singleThreadedDictionary = new Dictionary<string, string>(); singleThreadedDictionary.Add("Key", "Value");
I can even rewrite the above code as follows:
IDictionary<string, string> singleThreadedDictionary = new Dictionary<string, string>(); singleThreadedDictionary.Add("Key", "Value");
However, what if we try to do the same with the concurrent dictionary?
ConcurrentDictionary<string, string> concurrentDictionary = new ConcurrentDictionary<string, string>(); concurrentDictionary.Add("Key", "Value");
Visual Studio will complain that the ConcurrentDictionary object has no Add method. Errr.. where did it go? Let’s see if the interface declaration method works:
IDictionary<string, string> concurrentDictionary = new ConcurrentDictionary<string, string>(); concurrentDictionary.Add("Key", "Value");
It does indeed. At least the code compiles and Visual Studio can run the code.
How and why did this happen? Why is the Add method available for the Dictionary class and not the ConcurrentDictionary class if they are both IDictionary objects? This is made possible by a C# language feature called explicit interface implementation.
We’ve already seen an example of this feature in the post on building a custom enumerator:
public class Party : IEnumerable<Guest> { private IList<Guest> _guestList; public Party() { _guestList = new List<Guest>(); } public void AddGuest(Guest guest) { _guestList.Add(guest); } public IEnumerator<Guest> GetEnumerator() { foreach (Guest guest in _guestList) { yield return guest; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }
The…
public IEnumerator<Guest> GetEnumerator()
…implementation is an implicit implementation of the generic IEnumerable of T interface which returns an IEnumerator of T object.
The other method, i.e.
IEnumerator IEnumerable.GetEnumerator()
…is an explicit implementation of the non-generic IEnumerable interface which is inherited by the generic IEnumerable of T interface. Hence when we implement the generic IEnumerable of T interface we have to implement both the generic and the non-generic GetEnumerator methods.
Let’s find out more of this mystery in the next post.
View all various C# language feature related posts here.