Этот вопрос задают каждый день.Еще раз!
Можно ли использовать корзину с яблоками, когда вам нужна корзина с фруктами?Нет.
Почему бы и нет?Потому что вы можете положить банан в корзину с фруктами, но вы не можете положить банан в корзину с яблоками.
Поэтому вы не можете использовать корзину с яблоками, где нужна корзина с фруктами.
Аналогично, корзина с фруктами не может использоваться в качестве корзины с яблоками, поскольку она может уже содержать банан..
Отношение "a C<X>
может использоваться как C<Y>
, если X
может использоваться как Y
", называется ковариация , и C # поддерживает толькоковариация в очень ограниченном наборе обстоятельств:
C<T>
должен быть интерфейсом или делегатом - Объявление интерфейса или делегата должно быть помечено как безопасное для отклонения.
- Компилятор должен успешно проверить, что объявление отклонения гарантированно безопасно.
- Оба
X
и Y
должны быть ссылочными типами.
В вашем случае выу вас есть первое и четвертое свойства, но у вас нет второго и третьего.
Пометить IDataPointProcessor<T>
следующим образом:
interface IDataPointProcessor<out T>
, что примерно означает "T" используется только в выходных позициях, никогда не вводите позиции ".Если в корзинах нет возможности добавлять фрукты, то возражение - вы не можете положить банан в корзину с яблоками - исчезает, и оно становится законным.
Если сборка завершится успешно, ковариация начнет работатьIDataPointProcessor
.Если нет, вы, вероятно, используете T
в положении, когда T
может течь в .Правила немного более тонкие, чем я здесь обобщаю;если вам нужно подробное описание, я написал его здесь: https://blogs.msdn.microsoft.com/ericlippert/2009/12/03/exact-rules-for-variance-validity/
Вот почему вы можете использовать IEnumerable<Giraffe>
в качестве IEnumerable<Animal>
- все четыре условия соблюдены.