Welcome to MSDN Blogs Sign in | Join | Help

Syndication

Implicit and Explicit Interface Implementations

As I was putting together a post on IEnumerable and IEnumerator I was reminded of the subtleties of implicit and explicit interface implementations. C# does not support multiple inheritance, but a class has the option of implementing one or more interfaces. One challenge with interfaces is that they may include methods that have the same signatures as existing class members or members of other interfaces. Explicit interface implementations can be used to disambiguate class and interface methods that would otherwise conflict. Explicit interfaces can also be used to hide the details of an interface that the class developer considers private.

Disambiguating Methods

Let's look at an example of method disambiguation. In Listing 1 we have started to write a class called C that implements interfaces I1 and I2, each of which defines a method A().

Listing 1. Class C implements interfaces I1 and I2.

interface I1
{
    void A();
}

interface I2
{
    void A();
}

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

In this case, A() is a public class member that implicitly implements a member of both interfaces. A() can be invoked through either interface or through the class itself as follows:

Listing 2. A() can be invoked from I1, I2, or C.

C c = new C();
I1 i1 = (I1)c;
I2 i2 = (I2)c;

i1.A();
i2.A();
c.A();

The output from this code is

C.A()
C.A()
C.A()

This works fine if you want A() to do the same thing in both interfaces. In most cases, however, methods in different interfaces have distinct purposes requiring wholly different implementations. This is where explicit interface implementations come in handy. To explicitly implement an interface member, just use its fully qualified name in the declaration. A fully qualified interface name takes the form

InterfaceName.MemberName

In Listing 3 we add an explicit implementation of I1's A() method.

Listing 3. Class C explicitly implements I1.A().

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

    void I1.A()
    {
        Console.WriteLine("I1.A()");
    }
}

Now when we run the statements from Listing 2 we get

I1.A()
C.A()
C.A()

When an interface method is explicitly implemented, it is no longer visible as a public member of the class. The only way to access it is through the interface. As an example, suppose we deleted the implicit implementation of A() as shown in Listing 4:

Listing 4. Class C does not implicitly implement A()

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

In this case we would get a compile error saying that C fails to implement I2.A(). We could fix this error by changing the first line to

class C : I1

but we'd get another compile error when trying to invoke A() as a member of C:

C c = new C();
c.A();

This time the compiler would report that class C does not contain a definition for method A(). We get the error because the explicit implementation of I1.A() hides A() from the class. The only way to call I1.A() now is through C's I1 interface:

C c = new C();
I1 i1 = (I1)c;
i1.A();

Explicit interface implementations are sometimes necessary when classes implement multiple interfaces with conflicting member definitions. A common example involves collection enumerators that implement System.Collections.IEnumerator and System.Collections.Generic.IEnumerator.  In this case both interfaces specify a get-accessor for the Current property. To create a class that compiles, at least one of the two get-accessors must be explicitly implemented.

Hiding Interface Details.

In some cases explicit interface implementation can be useful even when disambiguation is unnecessary. One example is to use an explicit implementation to hide the details of an interface that the class developer considers private. While the level of privacy is not as great as that afforded by the private keyword, it can be useful in some circumstances. Listing 5 shows a common pattern involving IDisposable. In this case, the Dispose() method is hidden by explicit implementation because the method is really an implementation detail that is not germane to the users of class MyFile. At the very least, the explicit implementation keeps the interface members out of the class' Intellisense list.

Listing 5. Using explicit implementation to hide the details of IDisposable.

interface IDisposable
{
    void Dispose();
}

class MyFile : IDisposable
{
    void IDisposable.Dispose()
    {
        Close();
    }

    public void Close()
    {
        // Do what's necessary to close the file
        System.GC.SuppressFinalize(this);
    }
}

You can read more about implicit and explicit interface implementations in this MSDN Tutorial or in Version 1.2 of the C# Language Specification.

 

Hope this helps.

 

-Mike Hopcroft

 

kick it on DotNetKicks.com

Published Tuesday, December 12, 2006 11:59 PM by mhop

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Implicit and Explicit Interface Implementations @ Wednesday, December 13, 2006 3:02 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

DotNetKicks.com

# re: Implicit and Explicit Interface Implementations @ Wednesday, December 13, 2006 8:00 AM

Thanks, it's always useful to remind simple things sometimes.

Simone Busoli

# re: Implicit and Explicit Interface Implementations @ Thursday, December 14, 2006 6:31 PM

Thanks Mike. FYI, the difference between explicit and implicit implementations becomes a whole lot more subtle when you consider the possible semantics of multiple conflicting signatures under generic construction.  I wrote a bit about that here:

http://blogs.msdn.com/ericlippert/archive/2006/04/05/569085.aspx

and here:

http://blogs.msdn.com/ericlippert/archive/2006/04/06/570126.aspx

Eric Lippert

# Community Convergence XVI @ Friday, December 29, 2006 7:55 PM

Welcome to the sixteenth Community Convergence. This column comes out about once a week and is designed

Charlie Calvert's Community Blog

# re: Implicit and Explicit Interface Implementations @ Monday, January 15, 2007 6:30 PM

Nice, clear, explanation...thanks!

Paul

# re: Implicit and Explicit Interface Implementations @ Wednesday, November 14, 2007 12:15 AM

Thanks,It is very useful explanation of Implicit and Explicit Interface Implementations.It is really nice tutorial.

Jitendra Kumar

# re: Implicit and Explicit Interface Implementations @ Monday, December 10, 2007 11:44 PM

Thanks for the explanation.  I was watching an AppDev CBT video to review interfaces, and never really completely grokked the need for this until I saw your article.

Mark Freedman

# re: Implicit and Explicit Interface Implementations @ Thursday, April 03, 2008 10:09 PM

Thank you, this was very helpful.

Kyle McKee

# re: Implicit and Explicit Interface Implementations @ Wednesday, May 13, 2009 2:26 PM

Pretty neat, clear and pragmatic. Thanks a lot!

pavan

# re: Implicit and Explicit Interface Implementations @ Tuesday, June 30, 2009 2:12 AM

This is realy meaning full information.

Thanks

Hans

# re: Implicit and Explicit Interface Implementations @ Tuesday, August 04, 2009 5:00 AM

Really good article, Thanks very much Michael

Steven

# re: Implicit and Explicit Interface Implementations @ Friday, September 18, 2009 10:54 AM

Excellent. Very well written article.  Thanks!

David

# re: Implicit and Explicit Interface Implementations @ Monday, November 02, 2009 11:43 PM

Excellent.....

It really gives real insight into the implimentation of Interfaces....

Thanks.

Shivakumar Kampilla

# re: Implicit and Explicit Interface Implementations @ Thursday, November 12, 2009 2:46 PM

Great teaching!  thanks a bunch!

tvance929

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
Page view tracker