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" ковариантно.
Ответы
Ответ 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);
}