C# Interfaces. Implicit implementation versus 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?


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?


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 implemented as:

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

and explicitly as:

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

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

MyClass myClass = new MyClass(); // Declared as concrete class
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 implementations. But regardless I rarely use it.

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

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


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 members 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).

  • 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 functions 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.

    链接地址: http://www.djcxy.com/p/8900.html

    上一篇: StaticResource和WPF中的DynamicResource有什么区别?

    下一篇: C#接口。 隐式实现与显式实现