There is no such thing as "further filtering."
Filters are typically collected using the IEnumerable.Where extension method, which is defined for the IEnumerable interface. And since IList inherits from IEnumerable , you can call Where on both interfaces (calling Where on IList actually calls IEnumerable.Where ). Thus, in both cases the same base method is called, and the type of the resulting value will be IEnumerable (and not IList when applied to the list). This can be a source of confusion ("you can’t filter the IList further, since you don’t have it anymore?"), But nothing prevents you from filtering the resulting IEnumerable<T> again or even writing your own extension method that will create a new List for each call.
The post related to the question is of poor quality and should not be trusted.
See below for a detailed explanation.
You can filter elements from both interfaces almost the same, although in both cases you usually use IEnumerable extension methods (i.e. LINQ), since IList inherits from IEnumerable . And you can link as many Where statements as you like in both cases:
// `items` is an `IEnumerable<T>`, so we can call the `Where` extension method. // Each call creates a new instance, and keeps the previous one unmodified. IEnumerable<T> items = GetEnumerableItems(); var filteredItems = items .Where(i => i.Name == "Jane") // returns a new IEnumerable<T> .Where(i => i.Gender == "Female") // returns a new IEnumerable<T> .Where(i => i.Age == 30) // returns a new IEnumerable<T> // `list` is an `IList<T>`, which also inherits from `IEnumerable<T>`. // Calling `Where` on a list will also not modify the original list. IList<T> list = GetEnumerableItems(); var filteredList = list .Where(i => i.Name == "John") // returns a new IEnumerable<T> .Where(i => i.Gender == "Male") // returns a new IEnumerable<T> .Where(i => i.Age == 30) // returns a new IEnumerable<T> .ToList(); // returns a new List<T> (optional)
Googling for this term returns several articles mentioning it (for example, this or this ), all of them seem to copy the same source, it seems plagiarized without actual reasoning behind it. The only thing that may come to my mind is to apply Where to IEnumerable<T> to return a new (filtered) IEnumerable<T> so that you can apply Where again (further filter). But this is really vague, because applying Where to IList<T> will not stop you from filtering it, even if the resulting interface is IEnumerable<T> . As already mentioned in the comments, it is worth noting that the List<T> class, as a concrete implementation of IList<T> , provides a FindAll method that returns a new filtered concrete List<T> (and can be "additionally filtered"), but this is not part of IList<T> .
The main difference between re-filtering IEnumerable<T> and filtering the list into a new list (for example, using FindAll ) is that the latter needs to create a new List<T> instance at each step, and IEnumerable<T> uses delayed execution and not takes additional memory besides storing some state information for each Where call. And again, to avoid confusion, if you name Where on List<T> , you still get the benefits of IEnumerable<T> laziness.
Actual differences:
IList (or actually IList<T> , which I assume you are referencing) is a collection of objects that can be individually accessed by an index . This means that you can efficiently (in O(1) time) get the value of the object in a specific place, as well as the length of the list. The "bad thing" (assuming it is implemented as a List<T> under the hood), which means that you need to save the entire collection in memory.
The "only" IEnumerable (i.e. its generic counterpart IEnumerable<T> ) can do is iterate over elements (zero or more). It has no concept of an index (you cannot “skip” to an index without actually repeating or skipping all the elements in front of that element). And you also cannot use length effectively in the general case, without counting every time every time. IEnumerable , on the other hand, is evaluated by laziness, which means that its elements should not exist in memory until they are evaluated. It can wrap the database table below, with billions of rows extracted from disk when you iterate over it. It can even be an endless collection.