Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

interface covariance issue

The following code sample:

interface I<out T>
    where T : class, I<T>
{
    T GetT();
}

interface J : I<J>
{
}

abstract class B<T> : I<T>
    where T : B<T>
{
    T I<T>.GetT()
    {
        return null;
    }
}

class C : B<C>, J
{
}

fails to compile (under VS2010 with SP1) with the following error:

Error   4   'C' does not implement interface member 'I<J>.GetT()'

However, C does implement (through its base B<C>) I<C>, which, due to I being declared covariant, should capture I<J> as well (as C : J).

Is this a compiler bug? If not, why am I not allowed to do that?

like image 538
Grzegorz Herman Avatar asked Nov 05 '22 20:11

Grzegorz Herman


1 Answers

Even though it is covariant, you cannot change the return type of the interface. This is no different from the covariance in non-Generic classes.

interface Animal
{
    Animal GetAnimal();
}

class Cat : Animal
{
   //Not ALlowed
   Cat GetAnimal()
   {
       return this;
   }

   //Allowed
   Animal GetAnimal()
   {
       return this;
   }   
}

The problem is that C as a specialization of B<C> returns C I<C>.GetT(), however the specification of J requires J GetT().

Try the following:

interface I<out T>
    where T : class, I<T>
{
    T GetT();
}

interface J : I<J>
{
}

abstract class B<T,U> : I<U>
    where T : B<T,U>, U
    where U : class, I<U>
{
    U I<U>.GetT()
    {
        return null;
    }
}

class C : B<C,J>, J
{
}
like image 174
Ethan Cabiac Avatar answered Nov 09 '22 12:11

Ethan Cabiac