Почему я не могу использовать ковариацию с двумя типичными параметрами типа?
Рассмотрим следующий пример:
class Base {}
class Derived : Base {}
class Test1
{
private List<Derived> m_X;
public IEnumerable<Base> GetEnumerable()
{
return m_X;
}
}
Это компилируется просто отлично, потому что IEnumerable<T>
ковариантно в T
Однако, если я делаю то же самое, но теперь с дженериками:
class Test2<TBase, TDerived> where TDerived : TBase
{
private List<TDerived> m_X;
public IEnumerable<TBase> GetEnumerable()
{
return m_X;
}
}
Я получаю ошибку компилятора
Невозможно преобразовать тип выражения 'System.Collection.Generic.List' для возврата типа 'System.Collection.Generic.IEnumerable'
Что я здесь делаю неправильно?
Ответы
Ответ 1
Дело в том, что в первом случае Base
известна как класс. Во втором случае параметр типа T
может быть либо классом, либо структурой (так компилятор думает).
Решите случай, указав, что T
- класс, и ошибка исчезнет:
class Test2<TBase, TDerived> where TDerived : class, TBase
{
private List<TDerived> m_X;
public IEnumerable<TBase> GetEnumerable()
{
return m_X;
}
}
Таким образом, компилятор пытается показать нам, что TDerived может быть структурой (поскольку вы не указали ограничение class
), и, как мы уже знаем, ковариация и контравариантность не работают с структурами.