Мне кажется, что многие методы расширения на IList<T>
применимы к IEnumerable<T>
- например, FindAll
и RemoveAll
.
Может ли кто-нибудь объяснить, почему их там нет?
Мне кажется, что многие методы расширения на IList<T>
применимы к IEnumerable<T>
- например, FindAll
и RemoveAll
.
Может ли кто-нибудь объяснить, почему их там нет?
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;
Enumerable не означает, что существует базовая коллекция, поэтому вы не можете знать, есть ли что-то, что нужно удалить или нет. Если существует базовая коллекция, вы не знаете, поддерживает ли она операцию удаления.
Вот пример метода, который перечисляет нечетные числа. Если бы вы могли "удалить" 7 из перечислимого, что произойдет? Где он будет удален из?
public IEnumerable<int> GetOddPositiveNumbers()
{
int i = 0;
while (true)
{
yield return 2*(i++)+1;
}
}
То, что вы, возможно, ищете, - это Where
и Except
, что позволяет фильтровать перечисляемые.
Для RemoveAll
не применимо к IEnumerable
, потому что IEnumerable доступен только для чтения.
Для FindAll
см. Ответ Marc.
Все IEnumerable
указывает, что существует коллекция, которая может быть перечислина или переименована. Он даже не указывает, что сбор может быть повторен многократно, не говоря уже о манипулировании. Поэтому любые методы, управляющие коллекцией, не имеют смысла. Однако методы, такие как FindAll
, имеют смысл.
Чтобы быть справедливым, что-то вроде IEnumerable<T>.RemoveAll
может иметь смысл, если то, что вы на самом деле хотите, это версия нулевой длины конкретной коллекции. Вызов RemoveAll
не имеет смысла, поскольку реализация метода IEnumerable<T>
должна изменять коллекцию.
Поэтому в моем случае я иногда использую собственный метод расширения, который я вызываю Nil
.
static IEnumerable<T> Nil<T>(this IEnumerable<T> self) {
yield break;
}
Что касается FindAll
, как уже указывал Марк, просто называется Where
.