Ответ 1
Построенные типы вариантов интерфейсов (например, IEnumerable<out T>
) являются вариантами только для аргументов ссылочного типа, потому что их неявное преобразование в супертип (например, object
) является преобразованием, не изменяющим представление. Вот почему IEnumerable<string>
является ковариантным.
Построенные типы для аргументов типа значения являются инвариантными, потому что их неявное преобразование в супертип (например, object
) является изменением представления из-за бокса, который требовал. Вот почему IEnumerable<double>
является инвариантным.
Смотрите соответствующую документацию:
Отклонение применяется только к ссылочным типам; если вы укажете тип значения для параметра типа варианта, этот тип параметра является инвариантным для результирующего построенного типа.
Возможным обходным путем является использование LINQ cast:
var sequence = list.Cast<object>();
Сначала проверьте, соответствует ли источник совместимости с IEnumerable<TResult>
, с которой вы пытаетесь передать его.
- Если он совместим с назначением (как, например, для
T
являетсяstring
), он вернет исходный исходный код напрямую (это идеальный случай, по производительности). - Если он не совместим с назначением (как вы выяснили, например, для
T
являетсяdouble
), it создаст проекцию, которая будет пытаться преобразовать вручную для каждого отдельного элемента.