Explicit interface implementation in .NET

Introduction

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 first see how this language structure works in C#. Suppose we have the following interface:

public interface ISummable
{
	int Calculate(int a, int b);
}

We can then implement this interface implicitly as follows:

public class Calculator : ISummable
{
	public int Calculate(int a, int b)
	{
		return a + b;
	}
}

This should be straightforward for all programmers.

Let’s have another interface:

public interface IMultipliable
{
	int Calculate(int a, int b);
}

We then want our calculator to implement the above interface as well:

public class Calculator : ISummable, IMultipliable
{
	public int Calculate(int a, int b)
	{
		return a + b;
	}
}

As Calculator already has a Calculate method with two integer parameters it also satisfies IMultipliable without changing the Calculator object implementation.

This is problematic as we have no straightforward way to provide a multiplication for our calculator:

Calculator calculator = new Calculator();
int res = calculator.Calculate(2, 5);

“res” will be 7 of course.

We assume here that we cannot change the method names of ISummable and IMultipliable. They may be part of a third party library. One way out of this situation is to implement IMultipliable explicitly. If you right-click “IMultipliable” in Calculator.cs in Visual Studio you can select “Implement Interface”, “Implement Interface Explicitly” in the context menu. You’ll get the following stub:

public class Calculator : ISummable, IMultipliable
{
	public int Calculate(int a, int b)
	{
		return a + b;
	}

	int IMultipliable.Calculate(int a, int b)
	{
		throw new NotImplementedException();
	}
}

The structure of the new Calculate method looks very much like the non-generic GetEnumerator method of the second example of the previous post.

Explicitly implemented interface methods must not have any access modifiers. They are public by default.

Let’s implement the new method:

int IMultipliable.Calculate(int a, int b)
{
	return a * b;
}

How can we call this method? We have to declare Calculator as an interface type:

public void ShowSample()
{
	IMultipliable calculator = new Calculator();
	int res = calculator.Calculate(2, 5);
}

“res” will now be 10.

So now we can reach the Calculate methods as follows:

Calculator calc = new Calculator();
int calcCalculate = calc.Calculate(2, 5);

ISummable summable = new Calculator();
int calcSummable = summable.Calculate(2, 5);

IMultipliable multiplier = new Calculator();
int calcMultiplier = multiplier.Calculate(2, 5);

“calcCalculate” will be 7 as we call the Calculate method of the Calculator object. It was implicitly implemented from the ISummable interface.

“calcSummable” will also be 7 of course, as it calls the same implementation as above.

“calcMultiplier” will be 10 as it calls the explicitly implemented Calculate method of the IMultipliable interface.

There’s nothing stopping us from implementing both interfaces explicitly and remove the implicit Calculate implementation:

public class Calculator : ISummable, IMultipliable
{		
	int IMultipliable.Calculate(int a, int b)
	{
		return a * b;
	}

	int ISummable.Calculate(int a, int b)
	{
		return a + b;
	}
}

If we do that then the following code will cause the compiler to complain:

Calculator calc = new Calculator();
int calcCalculate = calc.Calculate(2, 5);

There’s no Calculate method defined for the Calculator object any more.

This solves the mystery behind the Add method of ConcurrentDictionary we saw in the beginning of this post:

ConcurrentDictionary<string, string> concurrentDictionary = new ConcurrentDictionary<string, string>();
concurrentDictionary.Add("Key", "Value");

The Add method of the IDictionary interface is explicitly implemented by the ConcurrentDictionary object. That’s why the Add method is not available directly on ConcurrentDictionary whereas it is available if we declare ConcurrentDictionary as an interface type:

IDictionary<string, string> concurrentDictionary = new ConcurrentDictionary<string, string>();
concurrentDictionary.Add("Key", "Value");

We still haven’t discussed why we’d ever choose to implement an interface explicitly. I can think of two reasons:

Method signatures

In C# two methods are considered the “same” if they have the same name and same input parameter types. Their return type doesn’t matter. The following code will cause the compiler to complain:

public bool Method(int i)
{
	return false;
}

public int Method(int input)
{
	return input + 2;
}

Those two methods have the same method signatures and cannot be overloaded based on their return types only. Consequently if you have two interfaces that provide methods of the same signature, like we saw before…:

public interface ISummable
{
	int Calculate(int a, int b);
}
public interface IMultipliable
{
	int Calculate(int a, int b);
}

…then the only option two implement both is to implement at least one of them explicitly. It doesn’t make any difference which. You can implement both of them explicitly as well.

Discourage usage

The above reasoning doesn’t explain why the Add method is not available directly on the ConcurrentDictionary object.

In that specific case Microsoft wanted to discourage the usage of the Add method which was meant for single-threaded usage just like in the “normal” Dictionary object. ConcurrentDictionary is meant to be used in multithreaded scenarios. The Add method was therefore explicitly implemented instead. It’s unlikely that people will declare a concurrent dictionary as an interface type:

IDictionary<string, string> concurrentDictionary = new ConcurrentDictionary<string, string>();

Therefore if you declare the ConcurrentDictionary like most people do…

ConcurrentDictionary<string, string> concurrentDictionary = new ConcurrentDictionary<string, string>();

…then you’ll be instead presented with the thread-safe TryAdd and AddOrUpdate methods so you’ll automatically be “redirected” to those methods.

So if you’d like to hide an implicit interface method from the consumers of an object an option is explicit interface implementation so that the interface method won’t be visible on the class.

View all various C# language feature related posts here.

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a comment

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.