Почему в IEnumerable <T>нет методов FindAll или RemoveAll? - PullRequest
13 голосов
/ 19 марта 2012

Мне кажется, что многие методы расширения на IList<T> так же применимы к IEnumerable<T>, как FindAll и RemoveAll.

Может кто-нибудь объяснить причину, почему онинет там?

Ответы [ 5 ]

21 голосов
/ 19 марта 2012

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;
9 голосов
/ 19 марта 2012

Enumerable не означает, что существует базовая коллекция, поэтому вы не можете знать, есть ли что-то для удаления или нет. Если является базовой коллекцией, вы не знаете, поддерживает ли она операцию удаления.

Вот пример метода, который перечисляет нечетные числа. Если бы вы могли «удалить» 7 из перечислимого, что бы произошло? Откуда оно будет удалено?

public IEnumerable<int> GetOddPositiveNumbers()
{
   int i = 0;
   while (true)
   {          
      yield return 2*(i++)+1;
   }
}

То, что вы можете искать, это Where и Except, которые позволяют фильтровать перечислимое.

1 голос
/ 02 сентября 2012

Если быть честным, то что-то вроде IEnumerable<T>.RemoveAll может иметь смысл, если на самом деле вам нужна версия конкретной коллекции нулевой длины.Вызывать его RemoveAll НЕ имеет смысла, поскольку реализация метода IEnumerable<T> не должна изменять коллекцию.

Так что в моем случае я иногда использую собственный метод расширения, который я вызываю Nil.

static IEnumerable<T> Nil<T>(this IEnumerable<T> self) {
  yield break;
} 

Что касается FindAll, как уже указал Марк, его просто называют Where.

1 голос
/ 19 марта 2012

Все IEnumerable указывает, что существует коллекция, которую можно перечислить или перебрать.Он даже не указывает, что коллекция может быть повторена несколько раз, не говоря уже о манипулировании.Поэтому любые методы, которые манипулируют коллекцией, не имеют смысла.Однако такие методы, как FindAll, имеют смысл.

1 голос
/ 19 марта 2012

Для RemoveAll не применимо для IEnumerable, потому что IEnumerable доступен только для чтения. Для FindAll см. Ответ Марка.

...