What is the purpose of hiding (using the "new" modifier) an interface method declaration?

The second example issues the following compiler warning:

'II2.F()' hides inherited member 'II1.F()'. Use the new keyword if hiding was intended.

I'd say the difference of using the new keyword is exactly that: showing intention.


The two are very different. By using 'new' you are creating a new inheritance chain. This means any implementations of II2 will need to realize both versions of F(), and the actual one you end up calling will depend upon the type of the reference.

Consider the following three realizations:

    class A1 : II1
    {
        public void F()
        {
            // realizes II1.F()
        }
    }

    class A2 : II2
    {
        void II1.F()
        {
            // realizes II1.F()
        }

        void II2.F()
        {
            // realizes II2.F()
        }
    }

    class A3 : II2
    {
        public void F()
        {
            // realizes II1.F()
        }

        void II2.F()
        {
            // realizes II2.F()
        }
    }

If you have a reference to A2, you will not be able to call either version of F() without first casting to II1 or II2.

A2 a2 = new A2();
a2.F(); // invalid as both are explicitly implemented
((II1) a2).F(); // calls the II1 implementation
((II2) a2).F(); // calls the II2 implementation

If you have a reference to A3, you will be able to call the II1 version directly as it is an implicit implentation:

A3 a3 = new A3();
a3.F(); // calls the II1 implementation
((II2) a3).F(); // calls the II2 implementation

I know of one good use for this: you have to do this to declare a COM interface that's derived from another COM interface. It is touched upon in this magazine article.

Fwiw, the author completely misidentifies the source of the problem, it has nothing to do with an 'inheritance tax'. COM simply leverages the way a typical C++ compiler implements multiple inheritance. There's one v-table for each base class, just what COM needs. The CLR doesn't do this, it doesn't support MI and there's only ever one v-table. Interface methods are merged into the v-table of the base class.