Если название не имело смысла, вот пример:Как создать ковариантный метод расширения на общем интерфейсе в C#?
interface IEat { void Eat; }
class Cat : IEat { void Eat { nom(); } }
class Dog : IEat { void Eat { nom(); nom();nom(); } }
class Labrador : Dog { }
Я хотел бы создать расширение метод, как это:
public static void FeedAll(this IEnumerable<out IEat> hungryAnimals) {
foreach(var animal in hungryAnimals) animal.Eat();
}
Так что я могу сделать это:
listOfCats.FeedAll();
listOfLabs.FeedAll();
listOfMixedHungryAnimals.FeedAll();
Возможно ли это? Где я неправ?
Приложение реального мира здесь - это то, что «Собака» является основным базовым классом в моем приложении, и есть много подклассов, каждый из которых может время от времени иметь ИЛИС вещей, которые должны выполнять групповые операции на их. Чтобы их просто называть методом расширения в списке интерфейса, который они все реализовали, будет субоптимальным.
Edit:
Я goofed в пример немного. Мой фактический код использует IList
, я надеялся, что доступны операции Count и index. Основываясь на ответах ниже, я предполагаю, что мне придется пойти в другом направлении для методов, которые требуют IList-семантики.
Не работает ли это без ключевого слова 'out'? 'IEnumerable' уже является 'IEnumerable ' из-за 'IEnumerable ', являющегося ковариантным. –
Стриланк, ты прав, я немного изменил свой вопрос. Хотел сделать это с IList, по-видимому, это невозможно (я понимаю, почему IList не ковариант, я просто надеялся, что это было обходным путем, тем более, что мне не нужно Add.) – richardtallent
В большинстве списков реализовано 'IReadOnlyList ' (к сожалению он не может быть помещен выше 'IList', так что это может сработать. –