Подпись правильного типа для возврата реализации - PullRequest
0 голосов
/ 10 июля 2020

В следующей ситуации:

/** contract */

abstract class A { }
abstract class B<T> where T : A { }   
abstract class K<M, N> where M:A where N: B<M>{}

/** implementation */

class RA : A { }
class RB : B<RA> { }
class RK : K<RA, RB> { }

/** usage/test */

class Test {
    RK rk = new RK();

    public K<T, TT> GetR<T, TT>() where T : A where TT : B <T> {
        return rk;
    }
}

Компилятор выдает ошибку на return rk:

Cannot convert expression type 'RK' to return type 'K<T,TT>'

Однако:

  • RA : A , поэтому он действителен для T : A
  • RB : B<RA>, поэтому он RB : B<T : A> и действителен для TT : B <T : A>
  • , наконец, RK : K<RA, RB>, поэтому это RK : K<T : A, TT : B<T>>, поэтому он должен быть тоже действителен

Вопросы:

  • Где ошибка в моем журнале c?

  • Что подпись должна GetR() иметь возможность возвращать как K<A, B<A>> все, что реализует K?

1 Ответ

1 голос
/ 10 июля 2020

Где ошибка в моем журнале c?

У вас есть метод, который является общим c для любых T и TT (с некоторыми ограничениями) но вы возвращаете реализацию с указанием c. Если вы вызываете K с любыми типами, кроме RA и RB, тип возврата будет несовместим.

Какая подпись должна GetR() иметь возможность возвращаться как K<A, B<A>> все, что реализует K?

Ваша подпись делает это - это определенное c возвращаемое значение , вызывающее ошибку. Вы можете сделать:

public K<T, TT> GetR<T, TT>() where T : A where TT : B <T> {
    return rk as K<T, TT>;
}

, который вернет null, если T и TT были чем-то другим, кроме RA и RB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...