Sunday, December 22, 2013

Explicit interface implementation Anti-pattern.

Explicit interface definition forces the members to be exposed only when you are working with the interface directly.

The main words are: Unexpected Behavior

Mostly used:
  • Implementing of several interfaces with the same members required different implementation.
  • Struggle with dependencies (very doubtful).
    Code with using more derived types knows nothing about interface's members that were implemented explicitly.
    For example in a ASP.NET MVP (Web Forms) control hide member used by presenter.
  • Work around for having same member with different logic in an interface and its derived class.
  • Some silly protection (by a run-time exception) from using of inappropriate interface members.
    As an example the array's explicit implementation for the ICollection<T>.Add() that will throw the NotSupportedException "Collection of a fixed size".

 Famous drawbacks:
  • It's greasy messy awful coding especially when used without a serious reason.
    It's definitely not an industrial programming.
  • Value type instances will be boxed when casted to an interface.
  • Cannot be called by a derived type
    (What is the struggle with dependencies on the other hand).
  • A virtual chain will be ignored and an explicit implementation will be called.
Microsoft's official guidelines (from first edition Framework Design Guidelines) states that using explicit implementations are not recommended, since it gives the code some unexpected behavior.
interface IMyInterface
    String Implicit { get; set; }
    String Explicit { get; set; }
    String ExplicitAndImplicit { get; set; }
    String OtherExplicit { get; set; }

interface IMyOtherInterface
   String OtherExplicit { get; set; }

class MyClass : IMyInterface, IMyOtherInterface
   String IMyInterface.Explicit { get; set; }

    String IMyInterface.ExplicitAndImplicit { get; set; }
    public String ExplicitAndImplicit { get; set; }

    public String Implicit { get; set; }

    String IMyInterface.OtherExplicit { get; set; }
    String IMyOtherInterface.OtherExplicit { get; set; }
    public String OtherExplicit { get; set; }

static void Main(string[] args)

    var myObject = new MyClass();
    var myInterface = (IMyInterface) myObject;
    var myOtherInterface = (IMyOtherInterface)myObject;

    myObject.Implicit = "Implicit";

    // Uncompilable code.
    //myObject.Explicit = "Explicit for the MyClass";
    myInterface.Explicit = "Explicit for the IMyInterface";

    myObject.ExplicitAndImplicit = "ExplicitAndImplicit for the MyClass";
    myInterface.ExplicitAndImplicit = "ExplicitAndImplicit for the IMyInterface";
    if(myObject.ExplicitAndImplicit == myInterface.ExplicitAndImplicit)
        throw new Exception("Blow mind");

    myInterface.OtherExplicit = "OtherExplicit for IMyInterface";
    myOtherInterface.OtherExplicit = "OtherExplicit for IMyOtherInterface";
    myObject.OtherExplicit = "OtherExplicit for MyClass";
    if (myInterface.OtherExplicit == myOtherInterface.OtherExplicit
        || myOtherInterface.OtherExplicit == myObject.OtherExplicit)
        throw new Exception("Blow mind");


No comments:

Post a Comment