проблема ковариации интерфейса - PullRequest
5 голосов
/ 06 июня 2011

Следующий пример кода:

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
{
}

не удается скомпилировать (под VS2010 с SP1) со следующей ошибкой:

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

Тем не менее, C реализует (через свою базу B ) I , который, поскольку я объявлен ковариантным, должен также захватывать I (как C: J).

Это ошибка компилятора? Если нет, то почему я не могу это сделать?

1 Ответ

2 голосов
/ 08 июня 2011

Несмотря на ковариантность, вы не можете изменить тип возвращаемого значения интерфейса .Это ничем не отличается от ковариации в неуниверсальных классах.

interface Animal
{
    Animal GetAnimal();
}

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

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

Проблема в том, что C в качестве специализации B<C> возвращает C I<C>.GetT(), однако для спецификации J требуется J GetT().

Попробуйте следующее:

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
{
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...