Long overdue update the the guidelines on Explicit member implementation. As always, feedback welcome.


Explicit Member
  Implementation

Explicit member implementation allows an interface member to be implemented such that it is only available when cast to the interface type.  For example consider the following definition:

public struct Int32 : IConvertible, IComparable {
   public override string ToString () {..}
   int ICovertible.ToInt32 () {..}
   ...
}

This code calls the IConvertable members:

int i = 42;
i.ToString();  // works
i.ToInt32();   // does not compile
((IConvertible) i).ToInt32();  // works

            Do not use explicit members as a security boundary. They can be called by any client who cast an instance to the interface.

*      Do use explicit members to hide implementation details

*      Do use explicit members to approximate private interface implementations.  If you need to implement an interface for only infrastructure reasons and you NEVER expect developers to directly call methods on that interface from this type then implement the members explicitly to “hide” them from public view.
For example, all of the base datatypes must implement IConvertable for infrastructure reasons.  IConvertable has 19 conversion methods that would pollute the public interface of these types.  So it is appropriate to explicitly implement these members so they are available when cast to IConvertable but do not appear on the public interfaces.  This makes the development experience much cleaner.

*      Do expose an alternative way to access any explicitly implemented members that subclasses are allowed to override.[1]  Use the same method name unless a conflict would arise.

The following example shows a type, ViolatingBase, that violates the rule and a type, FixedBase, that shows a fix for the violation.

using System;
 
namespace DesignLibrary
{
    public interface ITest
    {
        void SomeMethod();
    } 
    public class ViolatingBase : ITest
    {
        void ITest.SomeMethod()
        {
            // ...
        }
    }
    public class FixedBase : ITest
    {
        void ITest.SomeMethod()
        {
            SomeMethod();
        }
 
        virtual protected void SomeMethod()
        {
            // ...
        }
    }
    public class Derived : FixedBase, ITest
    {
        override protected void SomeMethod()
        {
            // ...
            base.SomeMethod();

            // This would cause recursion and a stack
            // overflow.
            // ((ITest)this).SomeMethod();
        }
    }
}

[1] Fully Covered by ExplicitMethodImplementationsInUnsealedClassesHaveVisibleAlternates