Как исправить эту ошибку? Недопустимая дисперсия: параметр типа «T» должен быть неизменно действительным на

У меня есть следующее сообщение об ошибке во время компиляции:

«Недопустимая дисперсия: параметр типа «T» должен быть неизменно действительным в «ConsoleApplication1.IRepository.GetAll ()». «T» является ковариантным».

и ниже мой код:

 class Program
{

    static void Main(string[] args)
    {
        IRepository<BaseClass> repository;

        repository = new RepositoryDerived1<Derived1>();

        Console.ReadLine();
    }
}

public abstract class BaseClass
{

}

public class Derived1 : BaseClass
{

}

public interface IRepository<out T> where T: BaseClass, new()
{
    IList<T> GetAll();
}

public class Derived2 : BaseClass
{

}

public abstract class RepositoryBase<T> : IRepository<T> where T: BaseClass, new()
{
    public abstract IList<T> GetAll();
}

public class RepositoryDerived1<T> : RepositoryBase<T> where T: BaseClass, new()
{
    public override IList<T> GetAll()
    {
        throw new NotImplementedException();
    }
}

Мне нужно было бы иметь возможность использовать вышеуказанный класс следующим образом:

репозиторий IRepository;

or

Репозиторий RepositoryBase;

Тогда я хотел бы иметь возможность назначить что-то вроде этого:

репозиторий = новый RepositoryDerived1();

Но это дает ошибку времени компиляции в классе IRepository.

Если я удалю ключевое слово «out» из класса IRepository, это даст мне еще одну ошибку, которая

«RepositoryDerived1» не может быть преобразован в «IRepository».

Почему и как это исправить?

Спасибо


person The Light    schedule 14.09.2011    source источник
comment
Как определяется RepositoryDerived1?   -  person Jeremy McGee    schedule 14.09.2011
comment
@Jeremy это показано в примере кода   -  person Marc Gravell    schedule 14.09.2011
comment
@Marc - ах, пропустил полосу прокрутки. Спасибо, тис.   -  person Jeremy McGee    schedule 14.09.2011


Ответы (1)


IList<T> не является ковариантным. Если вы измените IList<T> на IEnumerable<T> и удалите ограничение : new() из IRepository<out T> (поскольку абстрактный базовый класс этого не удовлетворяет), это будет работать:

public interface IRepository<out T> where T : BaseClass
{
    IEnumerable<T> GetAll();
}

public abstract class RepositoryBase<T> : IRepository<T> where T : BaseClass, new()
{
    public abstract IEnumerable<T> GetAll();
}

public class RepositoryDerived1<T> : RepositoryBase<T> where T : BaseClass, new()
{
    public override IEnumerable<T> GetAll()
    {
        throw new NotImplementedException();
    }
}
person Marc Gravell    schedule 14.09.2011
comment
спасибо, сам разобрался, а потом увидел твоё сообщение :) - отлично! - person The Light; 14.09.2011