Explicit Implementations


When implementing a member of an interface, it is possible to fully qualify its name with its interface name. Doing this creates an explicit interface member implementation, or explicit implementation, for short. For example, given

 interface IMyIF {   int myMeth(int x); }

then it is legal to implement IMyIF as shown here:

 class MyClass : IMyIF {   int IMyIF.myMeth(int x) {     return x / 3;   } }

As you can see, when the myMeth( ) member of IMyIF is implemented, its complete name, including its interface name, is specified. Notice that it is not preceded by the public access modifier. In general, you must use default access when explicitly implementing an interface member. Also, an explicit implementation must be called through an interface reference.

You might need to create an explicit implementation of an interface member for two reasons. First, when you implement a method using its fully qualified name, you are providing what amounts to a private implementation that is not exposed to code outside the class. Second, it is possible for a class to implement two interfaces, both of which declare methods with the same return type and signature. Fully qualifying the names removes the ambiguity from this situation. Let’s look at an example of each.

Creating a Private Implementation

The following program contains an interface called IEven, which defines two methods, isEven( ) and isOdd( ), which determine if a number is even or odd. MyClass then implements IEven. When it does so, it implements isOdd( ) explicitly.

 // Explicitly implement an interface member. using System; interface IEven {   bool isOdd(int x);   bool isEven(int x); } class MyClass : IEven {   // Explicit implementation. Notice that this member is private   // by default.   bool IEven.isOdd(int x) {     if((x%2) != 0) return true;     else return false;   }   // Normal implementation.   public bool isEven(int x) {     IEven o = this; // reference to invoking object     return !o.isOdd(x);   } } class Demo {   public static void Main() {     MyClass ob = new MyClass();     bool result;     result = ob.isEven(4);     if(result) Console.WriteLine("4 is even.");     // result = ob.isOdd(4); // Error, isOdd not directly accessible     // But, this is OK. It creates an IEven reference to a MyClass object     // and then calls isOdd() through that reference.     IEven iRef = (IEven) ob;     result = iRef.isOdd(3);     if(result) Console.WriteLine("3 is odd.");   } }

Since isOdd( ) is implemented explicitly, it cannot be specified as public in MyClass and is not directly available outside of MyClass. This makes its implementation effectively private. Inside MyClass, isOdd( ) can be accessed only through an interface reference. This is why it is invoked through o in the implementation for isEven( ).

Using Explicit Implementation to Remove Ambiguity

Here is an example in which two interfaces are implemented and both interfaces declare a method called meth( ). Explicit implementation is used to eliminate the ambiguity inherent in this situation.

 // Use explicit implementation to remove ambiguity. using System; interface IMyIF_A {   int meth(int x); } interface IMyIF_B {   int meth(int x); } // MyClass implements both interfaces. class MyClass : IMyIF_A, IMyIF_B {   // explicitly implement the two meth()s   int IMyIF_A.meth(int x) {     return x + x;   }   int IMyIF_B.meth(int x) {     return x * x;   }   // call meth() through an interface reference.   public int methA(int x){     IMyIF_A a_ob;     a_ob = this;     return a_ob.meth(x); // calls IMyIF_A   }   public int methB(int x){     IMyIF_B b_ob;     b_ob = this;     return b_ob.meth(x); // calls IMyIF_B   } } class FQIFNames {   public static void Main() {     MyClass ob = new MyClass();     Console.Write("Calling IMyIF_A.meth(): ");     Console.WriteLine(ob.methA(3));     Console.Write("Calling IMyIF_B.meth(): ");     Console.WriteLine(ob.methB(3));   } }

The output from this program is shown here:

 Calling IMyIF_A.meth(): 6 Calling IMyIF_B.meth(): 9

Looking at the program, first notice that meth( ) has the same declaration in both IMyIF_A and IMyIF_B. Thus, when MyClass implements both of these interfaces, it must explicitly implement each one separately, fully qualifying its name in the process. Since the only way that an explicitly implemented method can be called is on an interface reference, methA( ) creates a reference for IMyIF_A, and methB( ) creates a reference for IMy_IF_B. The methods then call meth( ) through these references, thereby removing the ambiguity.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net