Sunday, June 3, 2012

C#: Interfaces - Implicit and Explicit implementation


What are the differences in implementing interfaces implicitly and explicitly in C#?



When should you use implicit and when should you use explicit?



Are there any pros and/or cons to one or the other?


Source: Tips4all

9 comments:

  1. Implicit is when you define your interface via a member on your class. Explicit is when you define methods within your class on the interface. I know that sounds confusing but here is what I mean: IList.CopyTo would be implicitly implememnted as:

    public void CopyTo(Array array, int index)
    {
    throw new NotImplementedException();
    }


    and explicity as:

    void ICollection.CopyTo(Array array, int index)
    {
    throw new NotImplementedException();
    }


    The difference being that implicitly is accessible throuh your class you created when it is cast as that class as well as when its cast as the interface. Explicit implentation allows it to only be accessible when cast as the interface itself.

    myclass.CopyTo //invalid with explicit
    ((IList)myClass).CopyTo //valid with explicit.


    I use explicit primarily to keep the implementation clean, or when i need two implemetations. But regardless i rarely use it.

    I am sure there are more reasons to use it/not use it that others will post

    EIT: See the next post in this thread for excellent reasoning behind each.

    ReplyDelete
  2. Implicit definition would be to just add the methods / properties etc demanded by the interface directly to the class as public methods.

    Explicit definition forces the methods to be exposed only when you are working with the interface directly, and not the underlying implementation. This is preferred in most cases.


    By working directly with the interface, you are not acknowledging,
    and coupling your code to the underlying implementation.
    In the event that you already have, say, a public property Name in
    your code and you want to implement an interface that also has a
    Name property, doing it explicitly will keep the two separate. Even
    if they were doing the same thing I'd still delegate the explicit
    call to the Name property. You never know, you may want to change
    how Name works for the normal class and how Name, the interface
    property works later on.
    If you implement an interface implicitly then your class now exposes
    new behaviours that might only be relevant to a client of the
    interface and it means you aren't keeping your classes succinct
    enough (my opinion).

    ReplyDelete
  3. In addition to excellent answers already provided, there are some cases where explicit implementation is REQUIRED for the compiler to be able to figure out what is required. Take a look at IEnumerable<T> as a prime example that will likely come up fairly often.

    Here's an example:

    public abstract class StringList : IEnumerable<string>
    {
    private string[] _list = new string[] {"foo", "bar", "baz"};

    // ...

    #region IEnumerable<string> Members
    public IEnumerator<string> GetEnumerator()
    {
    foreach (string s in _list)
    { yield return s; }
    }
    #endregion

    #region IEnumerable Members
    IEnumerator IEnumerable.GetEnumerator()
    {
    return this.GetEnumerator();
    }
    #endregion
    }


    Here, IEnumerable<string> implements IEnumerable, hence we need to too. But hang on, both the generic and the normal version both implement funtions with the same method signature (C# ignores return type for this). This is completely legal and fine. How does the compiler resolve which to use? It forces you to only have, at most, one implicit definition, then it can resolve whatever it needs to.

    ie.

    StringList sl = new StringList();

    // uses the implicit definition.
    IEnumerator<string> enumerableString = sl.GetEnumerator();
    // same as above, only a little more explicit.
    IEnumerator<string> enumerableString2 = ((IEnumerable<string>)sl).GetEnumerator();
    // returns the same as above, but via the explicit definition
    IEnumerator enumerableStuff = ((IEnumerable)sl).GetEnumerator();


    PS: The little piece of indirection in the explicit definition for IEnumerable works because inside the function the compiler knows that the actual type of the variable is a StringList, and that's how it resolves the function call. Nifty little fact for implementing some of the layers of abstraction some of the .NET core interfaces seem to have accumulated.

    ReplyDelete
  4. Reason #1

    I tend to use explicit interface implementation when I want to discourage "programming to an implementation" (http://www.artima.com/lejava/articles/designprinciples.html).

    For example, in an MVP-based web app

    public interface INavigator {
    void Redirect(string url);
    }

    public sealed class StandardNavigator : INavigator {
    void INavigator.Redirect(string url) {
    Response.Redirect(url);
    }
    }


    Now another class (such as a presenter) is less likely to depend on the StandardNavigator implementation and more likely to depend on the INavigator interface (since the implementation would need to be cast to an interface to make use of the Redirect method).

    Reason #2

    Another reason I might go with an explicit interface implementation would be to keep a class's "default" interface cleaner. For example, if I were developing an ASP.NET server control, I might want two interfaces:


    The class's primary interface, which is used by web page developers; and
    A "hidden" interface used by the presenter that I develop to handle the control's logic


    A simple example follows. It's a combo box control that lists customers. In this example, the web page developer isn't interested in populating the list; instead, they just want to be able to select a customer by GUID or to obtain the selected customer's GUID. A presenter would populate the box on the first page load, and this presenter is encapsulated by the control.

    public sealed class CustomerComboBox : ComboBox, ICustomerComboBox {
    private readonly CustomerComboBoxPresenter presenter;

    public CustomerComboBox() {
    presenter = new CustomerComboBoxPresenter(this);
    }

    protected override void OnLoad() {
    if (!Page.IsPostBack) presenter.HandleFirstLoad();
    }

    // primary interface used by web page developers
    public Guid ClientId {
    get { return new Guid(SelectedItem.Value); }
    set { SelectedItem.Value = value.ToString(); }
    }

    // "hidden" interface used by presenter
    IEnumerable<CustomerDto> ICustomerComboBox.DataSource { set; }
    }


    The presenter populates the data source, and the web page developer never needs to be aware of its existence.

    But's It's Not a Silver Cannonball

    I wouldn't recommend always employing explicit interface implementations. Those are just two examples where they might be helpful.

    ReplyDelete
  5. In addition to the other reasons already stated, the is the situation in which a class is implementing 2 different interfaces that have a property/method with the same name and signiture.

    /// <summary>
    /// This is a Book
    /// </summary>
    interface IBook
    {
    string Title { get; }
    string ISBN { get; }
    }

    /// <summary>
    /// This is a Person
    /// </summary>
    interface IPerson
    {
    string Title { get; }
    string Forename { get; }
    string Surname { get; }
    }

    /// <summary>
    /// This is some freaky book-person.
    /// </summary>
    class Class1 : IBook, IPerson
    {
    /// <summary>
    /// This method is shared by both Book and Person
    /// </summary>
    public string Title
    {
    get
    {
    string personTitle = "Mr";
    string bookTitle = "The Hitchhikers Guide to the Galaxy";

    // What do we do here?
    return null;
    }
    }

    #region IPerson Members

    public string Forename
    {
    get { return "Lee"; }
    }

    public string Surname
    {
    get { return "Oades"; }
    }

    #endregion

    #region IBook Members

    public string ISBN
    {
    get { return "1-904048-46-3"; }
    }

    #endregion
    }


    This code compiles and runs ok, but the Title property is shared.

    Clearly, we'd want the value of Title returned to depend on whether we were treating Class1 as a Book or a Person. This is when we can use the explicit interface.

    string IBook.Title
    {
    get
    {
    return "The Hitchhikers Guide to the Galaxy";
    }
    }

    string IPerson.Title
    {
    get
    {
    return "Mr";
    }
    }

    public string Title
    {
    get { return "Still shared"; }
    }


    Notice that the explicit interface definitions are inferred to be Public - and hence you can't declare them to be public (or otherwise) explicitly.

    Note also that you can still have a "shared" version (as shown above) but whilst this is possible, the existence of such a property is questionable. Perhaps it could be used as a default implementation of Title - so that existing code would not have to be modified to cast Class1 to IBook or IPerson.

    If you do not define the "shared" (implicit) Title, consumers of Class1 must explictly cast instances of Class1 to IBook or IPerson first - otherwise the code will not compile.

    ReplyDelete
  6. Microsoft's official guidelines (from first edition Framework Design Guidelines) states that using explicit implementations are not recommended, since it gives the code unexpected behaviour.

    I think this guideline is very valid in a pre-IoC-time, when you don't pass things around as interfaces.

    Could anyone touch on that aspect as well?

    ReplyDelete
  7. To quote Jeffrey Richter from CLR via C#


    It is critically important for you to
    understand some ramifications that
    exist when using EIMIs. And because of
    these ramifications, you should try to
    avoid EIMIs as much as possible.
    Fortunately, generic interfaces help
    you avoid EIMIs quite a bit. But there
    may still be times when you will need
    to use them (such as implementing two
    interface methods with the same name
    and signature). Here are the big
    problems with EIMIs:


    There is no documentation explaining how a type specifically
    implements an EIMI method, and there
    is no Microsoft Visual Studio
    IntelliSense support.
    Value type instances are boxed when cast to an interface.
    An EIMI cannot be called by a derived type.



    Generally I see Interfaces as Semi (at best) OOP feature, it provides inheritance, but it does not provide real polymorphism. To get real polymorphism you NEED base class reference, it will guarantee that virtual methods chains are used correctly.

    If you use interface reference ANY virtual chain can be explicitly replaced with IEMI on any derived class and when object of such type is cast to interface your virtual chain is ignored and explicit implementation is called. Thats anything but polymorphism.

    IEMIs can be also used to hide non strongly typed interface members from basic Framework Interfaces implementations such as IEnumerable so your class doesn't expose non strongly typed method directly, but is syntaxical correct.

    ReplyDelete
  8. An implicit interface implementation is where you have a method with the same signature of the interface.

    An explicit interface implementation is where you explicitly declare which interface the method belongs to.

    interface I1
    {
    void implicitExample();
    }

    interface I2
    {
    void explicitExample();
    }


    class C : I1, I2
    {
    void implicitExample()
    {
    Console.WriteLine("I1.implicitExample()");
    }


    void I2.explicitExample()
    {
    Console.WriteLine("I2.explicitExample()");
    }
    }


    MSDN: implicit and explicit interface implementations

    ReplyDelete
  9. If you implement explicitly, you will only be able to reference the interface members through a reference that is of the type of the interface. A reference that is the type of the implementing class will not expose those interface members.

    If your implementing class is not public, except for the method used to create the class (which could be a factory or IOC container), and except for the interface methods (of course), then I don't see any advantage to explicitly implementing interfaces.

    Otherwise, explicitly implementing interfaces makes sure that references to your concrete implementing class are not used, allowing you to change that implementation at a later time. "Makes sure", I suppose, is the "advantage". A well-factored implementation can accomplish this without explicit implementation.

    The disadvantage, in my opinion, is that you will find yourself casting types to/from the interface in the implementation code that does have access to non-public members.

    Like many things, the advantage is the disadvantage (and vice-versa). Explicitly implementing interfaces will ensure that your concrete class implementation code is not exposed.

    ReplyDelete