Почему IEnumerable <T> не имеет методов FindAll или RemoveAll?
Мне кажется, что многие методы расширения на IList<T>
применимы к IEnumerable<T>
- например, FindAll
и RemoveAll
.
Может ли кто-нибудь объяснить, почему их там нет?
Ответы
Ответ 1
RemoveAll
не имеет смысла, поскольку в этом API нет Remove
и т.д., однако есть a FindAll
с 3,5 года, но он известен как Where
:
IEnumerable<Foo> source = ...
var filtered = source.Where(x => x.IsActive && x.Id = 25);
что эквивалентно:
IEnumerable<Foo> source = ...
var filtered = from x in source
where x.IsActive && x.Id == 25
select x;
Ответ 2
Enumerable не означает, что существует базовая коллекция, поэтому вы не можете знать, есть ли что-то, что нужно удалить или нет. Если существует базовая коллекция, вы не знаете, поддерживает ли она операцию удаления.
Вот пример метода, который перечисляет нечетные числа. Если бы вы могли "удалить" 7 из перечислимого, что произойдет? Где он будет удален из?
public IEnumerable<int> GetOddPositiveNumbers()
{
int i = 0;
while (true)
{
yield return 2*(i++)+1;
}
}
То, что вы, возможно, ищете, - это Where
и Except
, что позволяет фильтровать перечисляемые.
Ответ 3
Для RemoveAll
не применимо к IEnumerable
, потому что IEnumerable доступен только для чтения.
Для FindAll
см. Ответ Marc.
Ответ 4
Все IEnumerable
указывает, что существует коллекция, которая может быть перечислина или переименована. Он даже не указывает, что сбор может быть повторен многократно, не говоря уже о манипулировании. Поэтому любые методы, управляющие коллекцией, не имеют смысла. Однако методы, такие как FindAll
, имеют смысл.
Ответ 5
Чтобы быть справедливым, что-то вроде IEnumerable<T>.RemoveAll
может иметь смысл, если то, что вы на самом деле хотите, это версия нулевой длины конкретной коллекции. Вызов RemoveAll
не имеет смысла, поскольку реализация метода IEnumerable<T>
должна изменять коллекцию.
Поэтому в моем случае я иногда использую собственный метод расширения, который я вызываю Nil
.
static IEnumerable<T> Nil<T>(this IEnumerable<T> self) {
yield break;
}
Что касается FindAll
, как уже указывал Марк, просто называется Where
.