Interface implementation & casts.

Interface implementation & casts.

I’ve previously blogged about this unusual habit when implementing an interface:

Use explicit interface implementation.

 

      interface I

      {

      void F();

      }

      class C : I

      {

            void I.F()

            {

                  //...

            }

      }

 

I prefer my code to say “Here is where I satisfy the interface’s requirement that I implement method F()”. Otherwise you may think the method is there on its own merit.

The annoying thing about this approach is that it occasionally requires casts. If I have a ‘C’ and I want to call ‘F’ I have to cast. The cast is quite ugly. (Does it also have a perf impact?)

Here’s one way to deal with the problem:

 

      class C : I

      {

            public I I { get { return this; } }

            void I.F()

            {

                  //...

            }

      }

 

      // usage:

      C c = ...;

      c.I.F();

 

Don’t read this as “get the ‘I’ property from ‘c’ and call ‘F()’ on it.”

Read this as “call ‘I.F()’ on ‘c’.” Suddenly it makes perfect sense. The method I wrote was called “I.F()” so the method I call should be “I.F()”.

But there’s a catch. What do I do if the interface is generic?

      interface I<T>

      {

            void F();

      }

      class C<T> : I<T>

      {

            // what's the right name for this property?

            public I<T> I { get { return this; } }

            void I<T>.F()

            {

                  //...

            }

      }

You can’t have generic properties in C#.

I think I will call the property “I_T”. It’s not ideal, but I think I’ll cope.

Got any ideas about how to improve this further?

Comments

  • Anonymous
    June 18, 2004
    The comment has been removed
  • Anonymous
    June 18, 2004
    I think you example would have been okay. I think it's just that you can't have a property which introduces a new type parameter, so you can't have:

    class C<T>
    {
    U Property<U> where U: new
    {
    get { return new U(); }
    }
    }

    but you could do:

    class C<T> where T: ew
    {
    T Property<T>
    {
    get { return new T(); }
    }
    }


  • Anonymous
    June 18, 2004
    I usually implement my interfaces like that only when I don't want the type to expose that behaviour, but only when polymorphed to the interface type.
    I just think you're over-doing it a bit.
  • Anonymous
    June 19, 2004
    "I just think you're over-doing it a bit."

    Yeah, that's the point!

    http://blogs.msdn.com/jaybaz_ms/archive/2004/06/13/154918.aspx
  • Anonymous
    June 21, 2004
    I think this is a beautiful technique.
    I spent several hours playing with it over the weekend and will surely use it in the future.

    Often when I am implementing an interface, I am expecting the class to almost always be cast as the interface when used.

    I did some experiments using an inner DirectCastClass and a DirectCast property on the object. Passing my class to the DirectCastClass constructor let me use the same trick to not cast.

    As I played with it, I got to the point where I think it might be nice to somehow do this with attributes. To use an attribute to specify which base classes and interfaces whould be directly exposed.

    [ExposeDirectCast(typeof(I))]
    class C : I
    {
    void I.F()
    {
    }
    }

    Then be able to do.
    C.DirectCast.I.F();
    or maybe
    C.I.F();// but this might lead to confusion as to what I is.




  • Anonymous
    June 21, 2004
    What you are trying to do will not work in general....

    The following code is legal C#

    public class C : I {
    private I i_;

    public void I.F() {
    }

    public I I {
    get {
    reutrn i_;
    }
    }
    }


    However, your extension will introduce an ambiguity. Does the statement c.I.F() mean run the method I.F() on object c or run the method F on the object c.I?