Подтвердить что ты не робот

T должно быть контравариантно действительным

Что не так с этим?

interface IRepository<out T> where T : IBusinessEntity
{
    IQueryable<T> GetAll();
    void Save(T t);
    void Delete(T t);
}

В нем говорится:

Неверная дисперсия: параметр типа "T" должен быть контравариантно действителен в "MyNamespace.IRepository.Delete(T)". "T" ковариантно.

4b9b3361

Ответ 1

Подумайте, что произойдет, если компилятор допустил следующее:

interface IR<out T>
{
    void D(T t);
}

class C : IR<Mammal>
{
    public void D(Mammal m)
    {
        m.GrowHair();
    }
}
...
IR<Animal> x = new C(); 
// legal because T is covariant and Mammal is convertible to Animal
x.D(new Fish()); // legal because IR<Animal>.D takes an Animal

И ты просто попытался развить волосы на рыбе.

"Выход" означает, что "T используется только в выходных позициях". Вы используете его во входной позиции.

Ответ 2

Вы можете использовать параметр типа out только контравариантно, т.е. в возвращаемом типе. Следовательно, IQueryable<T> GetAll() является правильным, но void Delete(T t) не является.

Так как T используется как co-, так и контравариантно в вашем классе, вы не можете использовать out здесь (и in).

Вот немного фона: Ковариация и контравариантность (Wikipedia).

Ответ 3

Следующие два метода неверны:

void Save(T t);
void Delete(T t);

Вы не можете использовать T как аргумент метода. Только в качестве типа возврата, если вы хотите, чтобы он был ковариантным (out T) в вашем общем определении.

Или, если вам нужна контравариантность, вы можете использовать общий параметр только как аргумент метода, а не тип возвращаемого значения:

interface IRepository<in T> where T : IBusinessEntity
{
    void Save(T t);
    void Delete(T t);
}