One very common combination of the two is when implementing IEnumerable<T>
. Since IEnumerable<T>
inherits from IEnumerable
, then you must implement both IEnumerable<T>.GetEnumerator()
and IEnumerable.GetEnumerator()
. Since these have a different return type, but matching parameter list (empty), only one at most can be implicitly implemented.
The most common pattern is to implement the generic version:
public IEnumerator<T> GetEnumerator()
{
//some code that returns an appropriate object.
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();//return the result of the other call.
}
Now, one need not have either implicit, or one could (with a bit of casting in the explicit implementation) have this the other way around. However, this is handier for the following reasons:
- We probably would prefer that the implicit version is called, as its likely to have better type-safety and perhaps better efficiency if the enumerator object is dealt with through its more explicit interface.
- The implicit version will serve both calling code that wants an
IEnumerator<T>
and calling code that wants an IEnumerator
(as that's an implicit cast), and is hence the most useful.
Now, that case is one were we are forced to use an explicit interface. For an example of a case were we might choose to, consider writing a read-only list that wraps a List<T>
and implements IList<T>
.
All we have to do here is to delegate the reading operations to the wrapped list, and throw not supported for writing operations, e.g.:
public T this[int idx]
{
get
{
return _inner[idx];
}
set
{
throw new NotSupportedException("Read only list.");
}
}
public int Count
{
get
{
return _inner.Count;
}
}
public void Add(T item)
{
throw new NotSupportedException("Read only list.");
}
public bool IsReadOnly
{
get
{
return false;
}
}
And so on. However, this isn't very useful for people using the object by the concrete type, we've a whole bunch of members that either return the same result (IsReadOnly
) or always throw an exception. While code using the class through its interface has to be able to call these methods and properties, there's no value in doing so on the concrete class. Hence we can do as follows:
public T this[int idx]
{
get
{
return _inner[idx];
}
}
T IList<T>.this[int index]
{
get { return this[index]; }
set { throw new NotSupportedException("Collection is read-only."); }
}
public int Count
{
get
{
return _inner.Count;
}
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException("Read only list.");
}
bool ICollection<T>.IsReadOnly
{
get
{
return false;
}
}
Now while we fully implement IList<T>
we also offer a much cleaner and more useful interface (in the general rather than c# specific sense of "interface") to users of the concrete class.
Note that this builds precisely on the reason it normally makes more sense to be implicit: We've made all of these members more awkward for a user of the concrete class to get to (such code would have to cast to IList<T>
first). This is good here, as the only result of such awkward code is pointless or dangerous, and making bad ideas harder to do is a good thing. If such awkwardness was just getting in the way, it would be a different matter.