Explicit Interface Implementation

In the implementation shown so far, the class that implements the interface (Document) creates a member method with the same signature and return type as the method detailed in the interface. It is not necessary to explicitly state that Document is implementing IStorable, for example; the compiler understands this implicitly.

What happens, however, if the class implements two interfaces, each of which has a method with the same signature? This might happen if the class implements interfaces defined by two different organizations or even two different programmers. The next example creates two interfaces: IStorable and ITalk. ITalk implements a Read( ) method that reads a book aloud. Unfortunately, this conflicts with the Read( ) method in IStorable.

Because both IStorable and ITalk have a Read( ) method, the implementing Document class must use explicit implementation for at least one of the methods. With explicit implementation, the implementing class (Document) explicitly identifies the interface for the method:

void ITalk .Read( )

Marking the Read( ) method as a member of the ITalk interface resolves the conflict between the identical Read( ) methods. There are some additional aspects you should keep in mind.

First, the explicit implementation method cannot have an access modifier:

void ITalk.Read( )

This method is implicitly public. In fact, a method declared through explicit implementation cannot be declared with the abstract, virtual, override, or new keyword, either.

Most importantly, you cannot access the explicitly implemented method through the object itself. When you write:

theDoc.Read( );

the compiler assumes you mean the implicitly implemented interface for IStorable. The only way to access an explicitly implemented interface is through a cast to the interface:

ITalk itDoc = theDoc as ITalk;
if (itDoc != null)
{
 itDoc.Read( );
}

Explicit implementation is demonstrated in Example 13-6. Note that there is no need to use explicit implementation with the other method of ITalk:

public void Talk( )

Because there is no conflict, this can be declared as usual.

Example 13-6. Explicit implementation allows you to avoid conflicts when two interfaces have methods with the same name

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Example_13_6_ _ _ _Explicit_Interfaces
{
    interface IStorable
    {
        void Read( );
        void Write( );
    }

    interface ITalk
    {
        void Talk( );
        void Read( );
    }

    // Modify Document to also implement ITalk
    public class Document : IStorable, ITalk
    {

        // the document constructor
        public Document(string s)
        {
            Console.WriteLine("Creating document with: {0}", s);
        }

        // Implicit implementation
        public virtual void Read( )
        {
            Console.WriteLine("Document Read Method for IStorable");
        }

        public void Write( )
        {
            Console.WriteLine("Document Write Method for IStorable");
        }

        // Explicit implementation
        void ITalk.Read( )
        {
            Console.WriteLine("Implementing ITalk.Read");
        }

        public void Talk( )
        {
            Console.WriteLine("Implementing ITalk.Talk");
        }
    }

    class Tester
    {
        public void Run( )
        {
            // Create a Document object
            Document theDoc = new Document("Test Document");
            IStorable isDoc = theDoc as IStorable;
            if (isDoc != null)
            {
                isDoc.Read( );
            }

            // Cast to an ITalk interface
            ITalk itDoc = theDoc as ITalk;
            if (itDoc != null)
            {
                itDoc.Read( );
            }

            theDoc.Read( );
            theDoc.Talk( );

        }

        static void Main( )
        {
            Tester t = new Tester( );
            t.Run( );
        }
    }
}

The output looks like this:

Creating document with: Test Document
Document Read Method for IStorable
Implementing ITalk.Read
Document Read Method for IStorable
Implementing ITalk.Talk

The first thing the program does is create an IStorable reference to a Document. Then it invokes the Read( ) method of IStorable:

IStorable isDoc = theDoc as IStorable;
if (isDoc != null)
{
    isDoc.Read( );
}

Then you cast the document to an ITalk interface, and invoke the Read( ) method of ITalk:

ITalk itDoc = theDoc as ITalk;
if (itDoc != null)
{
    itDoc.Read( );
}

The output shows that both of these calls work as expected.

The next thing you do is to call the Read( ) and Talk( ) methods directly on the Document:

theDoc.Read( );
theDoc.Talk( );

As you can see in the output, the Read( ) method defaults to the version from IStorable, because that version is implicit. The Talk( ) method is the version from ITalk, because that’s the only interface here with a Talk( ) method.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset