DekGenius.com
Team LiB   Previous Section   Next Section

14.7 Explicit Interface Implementation

In the implementation shown so far, the implementing class (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 this is an implementation of an interface; this is understood by the compiler 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. The latter 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 keywords.

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 14-7.

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 14-7. Explicit implementation
using System;

namespace OverridingInterfaces
{
    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();
      }

      [STAThread]
      static void Main()
      {
         Tester t = new Tester();
         t.Run();
      }
   }
}
Output:
Creating document with: Test Document
Document Read Method for IStorable
Implementing ITalk.Read
Document Read Method for IStorable
Implementing ITalk.Talk

    Team LiB   Previous Section   Next Section